Angular Convert POST request data to array - node.js

I have a post request that sends some data to a NodeJS app and then that returns an array. My problem is that I can't turn the data I receive as a response from the POST request to an array.
My Angular is set up like this:
newWord = '';
keyword = '';
onClick() {
const headers = new HttpHeaders()
.set('Authorization', 'my-auth-token')
.set('Content-Type', 'application/json');
this.http.post('http://localhost:3000/search',
{ keyword: this.keyword },
{
headers: headers
})
.subscribe((data) => {
console.log(data);
})
}
}
The data inside the node app looks like this:
I want to get this data in angular as an array so I can iterate over it or do anything else with the fields. Any help would be appreciated!

Provide the type to the http request. Otherwise angular expects any, which is not necessarily an array. That is where the error comes from.
this.http.post<{ id: string, text: string }[]>('http://localhost:3000/search',
{ keyword: this.keyword },
{
headers: headers
})
.subscribe((data) => {
console.log(data);
})

Related

forward the response of http request to the client

I am invoking a web service through an azure function in node.js with Axios, I have a couple of questions here.
1- in the body of this request I'm hardcoding the value for appUser. however, if I want to run this request on postman and pass the JSON value in the body for appUserwhat changes do I need to do in the code so the param value can pick up what is being passed.
2- the response for this request is only returned in the console of the editor but not getting sent to the client response body (i.e. postman) any idea how to forward the response?
module.exports = async function () {
const axios = require("axios");
const data = {
appUser: "yamen",
};
const headers = {
Authorization:
"Basic WUFNkVQRDg9",
};
{
axios
.post(
"https://tegossl/GetAppUser?company=Enva",
data,
{ headers: headers }
)
.then((response) => {
console.log(`Status: ${response.status}`);
console.log("data: ", response.data);
})
.catch((err) => {
console.error(err);
});
}
};

form-data request body is empty

I'm trying to send an image and some data from an API to another. The image is stored in memory with multer. But when I want to send it, the body is just empty. I tried the same request with postman and it worked perfectly.
postman test
postman test image
server test
server test image
Here is some code. I removed some of it so you can read it better
export const saveImage = async ({ image, name, folder, options }: { image: any, name?: any, folder: string, options?: any }) => {
try {
const fd = new FormData();
fd.append("image", image.buffer, image.originalname);
if(options) {
fd.append("options[resize][height]", options?.resize?.height);
fd.append("options[resize][width]", options?.resize?.width);
}
if(name) fd.append("name", name);
fd.append("folder", folder);
fd.append("servideId", IMAGES_ID);
fd.append("serviceSecret", IMAGES_SECRET);
console.log(fd)
const formHeaders = fd.getHeaders();
const request = await axios.post(`${IMAGES_URL}/api/images`, {
headers: formHeaders,
body: fd
});
return request.data.id;
} catch (error) {
const { response } = error;
console.log(response.request.data)
if(error?.response?.data?.error) {
throw { statusCode: error.response.status, message: error.response.data.error }
}
console.error("Images API", error);
throw new InternalError("Something gone wrong");
}
}
When I log the FormData, I can see in _streams, the data that I'm sending, but the Images API receives an empty body.
FormData screenshot
If you need more information tell me, please! Thank you
The axios API for the post method is: axios.post(url[, data[, config]]). The second argument must always be the data you send along.
In your case axios thinks { headers: formHeaders, body: fd } is the body and the request ends up being application/json. To send a file with data using axios in Node.js, do the following:
const response = await axios.post(`${IMAGES_URL}/api/images`, fd, {
headers: {
...formHeaders,
'X-Custom-Header': 'lala', // optional
},
});
Your question inspired me to turn this answer into an article — Send a File With Axios in Node.js. It covers a few common pitfalls and you'll learn how to send files that are stored as a Buffer or coming from a Stream.
With Axios, you can directly use the form data without having to deal with headers.
axios.post("/api/images", fd)
If you wish to modify headers at some point in the future, you should pass the formData to the `data` field instead of `body`.
axios.post("/api/images", { headers: formHeaders, data: fd })
Correction in comments.
It can also be done using the Axios API syntax.
axios({method: 'post', url: 'url', data: fd, headers: {} })
In the backend, multer will add your files to req.file instead of req.body, if you have properly configured it to do so.

Cannot get post working in Angular2

So i'm trying to authenticate in my angular application. I attended headers and created an stringified body. I also looked at serveral other forum post about sending post requests in postman but i cannot get it working.
getToken()
{
console.log('started getting of token');
//get username and password from local storage
//Send username and password via body
let headers = new Headers();
let body = JSON.stringify({
name: 'test',
password: 'test'
});
headers.append('Content-Type', 'application/x-www-form-urlencoded');
this.jwt = this.http.post('http://localhost:8080/api/authenticate/', {
headers: headers,
body: body
}).map(res => res.text()).subscribe(data => console.log(data));
}
So above is my code. I know it might be a little silly thing but I cannot get it working.
I get the error that the user cannot be found. That happens when the username is wrong, and when the username does not exsist in the database. So that a little extra tricky as well.
Who knows what the stupid mistake is that I made?
Add this code in your service.ts file.
import { Http, URLSearchParams} from '#angular/http';
getToken()
{
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let body = new URLSearchParams();
body.set('name', test);
body.set('password', test);
return this.http.post("http://localhost:8080/api/authenticate/", body, headers).map(response => response.json());
}
Use following code to send post request
this.jwt = this.http.post('http://localhost:8080/api/authenticate/',body,headers).map(res => res.text()).subscribe(data => console.log(data));
This code is what I use for post request
send_request_post(url: String, data:{})
{
var headerPost = new Headers
({
'Content-Type' : 'application/json ;charset=utf-8'
})
return this.http.post(url, JSON.stringify(data), {headers: headerPost})
.toPromise()
.then
(
response =>
{
console.log(response);
}
)
}

Add a json object to req.body

I have learnt about sending form values via req.body. How can I append a new value/json to it? For eg. if the form contains only one or two input fields and submit, which sends a post request, how do i append a json object to the req.body recieved by express server?
I am designing a rest api with express for angular to access. I need to send json to express for post requests. It is a shopping cart(as a json object of products and rates) which i have to send to the backend to place an order(store in mongo).
Any suggestions?
You have to set the content-type to application/json. You can build your JSON object from the form data:
var data = {
id: form-model-id,
name: form-model-name
}
For more information see ng-http
$http.post('http://127.0.0.1:3000/something/cool', data, {
headers: {'Content-Type': 'application/json'},
}).then(function (response) {
callback(null, response.data);
}, function (response) {
if (response.status === 0) {
throw { message: 'api_timeout' };
} else {
if (response.status === 409) {
throw { message: 'api_login_failed' };
} else {
callback(response.status, response.data);
}
}
});

How to post multipart/form-data with node.js superagent

I am trying to send the content-type in my superagent post request to multipart/form-data.
var myagent = superagent.agent();
myagent
.post('http://localhost/endpoint')
.set('api_key', apikey)
.set('Content-Type', 'multipart/form-data')
.send(fields)
.end(function(error, response){
if(error) {
console.log("Error: " + error);
}
});
The error I get is:
TypeError: Argument must be a string
If I remove the:
.set('Content-Type', 'multipart/form-data')
I don't get any error but my back end is receiving the request as content-type: application/json
How can I force the content type to be multipart/form-data so that I can access req.files()?
First, you do not mention either of the following:
.set('Content-Type', 'multipart/form-data')
OR
.type('form')
Second, you do not use the .send, you use .field(name, value).
Examples
Let's say you wanted to send a form-data request with the following:
two text fields: name and phone
one file: photo
So your request will be something like this:
superagent
.post( 'https://example.com/api/foo.bar' )
.set('Authorization', '...')
.accept('application/json')
.field('name', 'My name')
.field('phone', 'My phone')
.attach('photo', 'path/to/photo.gif')
.then((result) => {
// process the result here
})
.catch((err) => {
throw err;
});
And, let's say you wanted to send JSON as a value of one of your fields, then you'd do this.
try {
await superagent
.post( 'https://example.com/api/dog.crow' )
.accept('application/json')
.field('data', JSON.stringify({ name: 'value' }))
}
catch ( ex ) {
// .catch() stuff
}
// .then() stuff...
Try
.type('form')
instead of
.set('Content-Type', 'multipart/form-data')
See http://visionmedia.github.io/superagent/#setting-the-content-type
It is not clear what is in the fields variable that you are sending, but here is some information that may help you determine where your problem lies.
To begin with, if you are actually trying to build a multi-part request, this is the official documentation for doing so: http://visionmedia.github.com/superagent/#multipart-requests
as for the error that you got...
The reason is that during the process of preparing the request, SuperAgent checks the data to be sent to see if it is a string. If it is not, it attempts to serialize the data based on the value of the 'Content-Type', as seen below:
exports.serialize = {
'application/x-www-form-urlencoded': qs.stringify,
'application/json': JSON.stringify
};
which is used here:
// body
if ('HEAD' != method && !req._headerSent) {
// serialize stuff
if ('string' != typeof data) {
var serialize = exports.serialize[req.getHeader('Content-Type')];
if (serialize) data = serialize(data);
}
// content-length
if (data && !req.getHeader('Content-Length')) {
this.set('Content-Length', Buffer.byteLength(data));
}
}
this means that to set a form 'Content-Type' manually you would use
.set('Content-Type', 'application/x-www-form-urlencoded')
or
.type('form') as risyasin mentioned
any other 'Content-Type' will not be serialized, and Buffer.byteLength(data) will subsequently throw the TypeError: Argument must be a string exception if the value of your fields variable is not a string.
Here is what worked for me. I had a single field form, that was uploading a file. I turned the form into a HTML5 FormData element and then did it as follows:
var frm = new FormData(document.getElementById('formId'));
var url = 'url/here';
superagent.post(url)
.attach('fieldInFormName', frm.get('fieldInFormName'))
.end( function (error, response) {
//handle response
});
Please note, I tried various ways of setting the 'Content-Type' manually in superagent, and it never worked correctly because of the multipart identifier needed in the Content-Type.

Resources