Body-parser to avoid "JSON.parse(body)" - javascript

In express I can use a middleware called "body-parser" to automatically parse the incoming body.
Now that I do not have an express router to apply the middleware to, is it possible to somehow apply it to all requests in my chai test file? So that I can achieve the DRY principle.
I currently use this in every test:
it('login', done => {
request.post('http://localhost:3000', (err, res, body) => {
JSON.parse(body) // <-- I have to parse the body each time
done();
})
});

I'm assuming you are using the Request library. And if I'm understanding your question correctly, you want request to automatically parse your response body via JSON.parse.
The documentation explains how to do that under https://github.com/request/request#requestoptions-callback
json - sets body to JSON representation of value and adds Content-type: application/json header. Additionally, parses the response body as JSON.
So your code should be something like:
request.post({url: 'http://localhost:3000', json: true}, (err, res, body) => {
console.log(res)
console.log(body)
})
Untested, but that's what I gather from reading the docs.

Related

How can I view the body data of an HTTP request in a Firebase Functions JS?

"I'm trying to view the body data in a Firebase Functions POST request, but the console always returns "undefined" in the Firebase function logs!
Question: How can I view the body data in a Firebase function to use it?
Request :
Here My Code :
exports.test = functions.https.onRequest(async (req, res) => {
const id = req.body.id
});
I allready used but not working :
req.on('data', (chunk) => {
// The chunk is a Buffer object containing a chunk of the request body data
body += chunk;
}).on('end', () => {
// The request body data has been fully received, and the `body` variable contains the complete request body
});
i should to get id from body.id
As per this thread’s answer you should use Content-Type and make it to "application/json"
as only then your body will be accessible like as shown in here
Also you can check out Read values from the request which explains the need of application/json on Content Type.
If you check the firebase functions logs you can see there is no incoming body received from the request and because of that your body content’s are undefined.
There is also a possibility that the req.body property in a Firebase Functions is not properly formatted or if it is not properly parsed by the Function, so you can force it to parse using JSON.parse(req.body); to parse the request body.
So the updated code will something look like:
exports.test = functions.https.onRequest(async (req, res) => {
const body = JSON.parse(req.body);
const id = body.id;
// ...
});
OR
You can use the body parser middleware and force parse the body as JSON as shown in this answer
req.body can be used if the request body type is application/json or application/x-www-form-urlencoded otherwise use req.rawBody

Read Body from IncomingMessage Object in a Google Cloud Function with node.js

I have a Google Cloud Function based on node.js 8 and I'd like to process the body of the IncomingMessage object. I can't access the body via req.body as lined out in the Google Examples. I get req.body is undefined.
If I log the req object, I get an IncomingMessage object, hence I try to read the body as explained here and I end up with the following implementation.
'use strict';
exports.insertSuccessfulConsent = (req, res) => {
console.log(`METHOD: ${req.method}`);
console.log(`HEADERS: ${JSON.stringify(req.headers)}`);
let body = "";
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
console.log(body);
});
console.log('Body: ' + body);
let message = 'POST processed';
res.status(200).send(message);
};
Unfortunately the body is empty, although the HTTP POST request has data in the body. This is my test call:
curl -X POST HTTP_TRIGGER_ENDPOINT -H "Content-Type:application/json" -d '{"name":"Jane"}'
Headers and HTTP Methods are correct in the log, only the body is missing.
Question is: How to I get the Body from the req object?
I'm not sure but in the example written by Google they are referencing Express and you referenced a solution for an issue with NodeJS plain http module. I'm not sure if it fits here, despite that being used by express itself.
Is your listener for the 'data' event even being called? If not, that's the reason why your body is empty, you defined it as empty before and your listener never got called by the data event.
The reason why your req.data is set as undefined is probably because it is undefined by default in Express. You will need a parser as express points out on its documentation.
You can use something like body-parser module for populating your req.body.
I hope it helps.

How to extract req.body on the server side (I'm using fetch)?

I'm making a project that consists of separate frontend and backend. From the frontend, I make a POST request via fetch that should send a string 'ORANGE' to the backend and then the backend should log it to the console. I can't get the backend to console log the string. I looked at the request in devtools and the string 'ORANGE' was buried there under 'Request payload'. The request itself was sent alright. How do I actually access the string so I can do things with it? (eg, store in database)
//FRONTEND
const commentForm = document.getElementById("editform");
commentForm.addEventListener('submit', function(e) {
e.preventDefault();
fetch('http://localhost:3000/posts/:id', {
mode: 'cors',
method: 'post',
headers: {
"Content-type": "text/plain;charset=UTF-8"
},
body: "ORANGE"
}).then(function(response) {
if (response.ok) {
console.log("response.ok was true: "+ response)
} else {
let error = new Error(response.statusText)
error.response = response
throw error
}
})
});
//BACKEND
router.post('/posts/:id', function(req, res, next) {
console.log('What do I put here to get ORANGE logged?!')
//On the server side I tried some console.log tests.
//console.log("req is " + req); //req is [object Object]
//console.log("type of req is " + typeof req); //type of req is object
//console.log(JSON.parse(req)); //SyntaxError: unexpected token o in JSON at position 1
res.send('whatever. I want ORANGE.')
}
Try for the following:
Use body parser in your server.js file.
Send post request as content-type as json as follows,
headers: { Content-Type: application/json }
and body should be a JSON
body: {"color":"ORANGE"}
In your route just print
console.log(req.body.color)
Express won't, by default, process the body of a request. You need to load a module to do so explicitly.
Since you are using plain text, you can use the body-parser module. This will create a body property on the request:
const bodyParser = require('body-parser');
router.use(bodyParser.text({type: 'text/plain'}))
router.post('/posts/:id', function(req, res, next) {
console.log(req.body);
res.send('Response')
});
Note, however, that it is generally better to use a structured data format like JSON rather than plain text.
In Express 4.16 body-parser module isn't necessary anymore. All you need for getting the body is:
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
Use "Content-type": "application/x-www-form-urlencoded" inside the fetch otherwise CORS will send preflights and give you a hard time. (for more on this google CORS simple request requirements).
As in the documentation of fetch() explained:
This is just an HTTP response, not the actual JSON. To extract the JSON body
content from the response, we use the json() method (defined on the Body mixin,
which is implemented by both the Request and Response objects.)
const response = await fetch('http://example.com/movies.json');
const myJson = await response.json();
console.log(JSON.stringify(myJson));
so you don't have a body object inside your response, only a json object, which is your body.

making post request issue

I'm trying to print the data received from the body yet not working. Here is my attempt ...
router.post('/api/main',(req,res) => {
if(req.error){
res.status(400).send(error.details[0].message);
return;
}
res.send(req.body.message)
})
on postmen Im making a post request like these: localhost:5000/api/main/
the body looks like these: JSON
{
"message": "hello"
}
However, im getting this response
{
"success": false,
"msg": {}
}
What am I missing
Add body parser as middleware on your post router.
Here's the proper way to set your body parser middleware.
router.use(bodyParser.urlencoded({extended: true});
router.post('/api/main', (req, res) ...)
You may also want to use bodyParser.json()
in your index file, before using any routers, add app.use(bodyParser.urlEncoded({extended: true}));

Data is not passed from AngularJS controller to NodeJS server

I am attempting to pass some values from my client-side AngularJS script to a server-side NodeJS script. I set up the POST request like so:
$scope.addUser = function() {
console.log($.param($scope.user));
$http({
method: 'POST',
url: '/addUser',
data: $.param($scope.user),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).
success( function(response) {
console.log("success");
}).
error( function(response) {
console.log("error");
});
};
The $scope.user variable is { name: "john", email: "doe" }, and evaluates to name=john&email=doe when passed through $.param($scope.user). I originally thought the problem was the content-type of the request, which was originally a JSON object. After reading about similar problems I changed the content-type to x-www-form-urlencoded, but still could not grab the data from the POST request.
Here is the server-side NodeJS script that is hit with the POST request:
app.post('/addUser', function(req, res) {
console.log(req.params);
});
I know the server-side script is being reached, as I can print out data such as req.method, but attempting to print req.params results in just { }.
Why are my POST parameters not going through?
Request bodies are not saved to req.params. You need to add a middleware to parse the request body for you. req.params is for key=value pairs supplied as part of the URL (e.g. POSTing to "/foo/bar?baz=bla" would result in req.params.baz === 'bla').
Some example solutions:
body-parser - parses only application/json and application/x-www-form-urlencoded request bodies.
formidable - parses application/json, application/x-www-form-urlencoded, and multipart/form-data. This is what was used in the body parser in Express 3. I'm not sure if there is an "official" Express middleware for it for Express 4.
busboy - parses application/x-www-form-urlencoded and multipart/form-data. It does not save files to disk itself, but instead presents files as readable streams. The API differs from formidable(/body parser from Express 3). There are a few Express middleware available for busboy:
connect-busboy - a thin wrapper that merely sets up a Busboy instance on your req. You can set it to automatically start parsing the request, or you can pipe the request manually to req.busboy when you want to start.
multer - provides an interface more similar to the Express 3 body parser middleware (with req.body and req.files set).
reformed - a new module that provides a layer on top of Busboy to provide mechanisms similar to formidable (e.g. saving uploaded files to disk) but also other features such as field validation.
Since you are using express.js your POST fields are received as part of the body not the URL so you need use body instead of params:
app.post('/addUser', function(req, res) {
console.log(req.body);//also possible req.body.name | req.body.email
});
How about trying a simpler POST something like this (for testing purposes only):
$http.post('/addUser',{ "name": "john", "email": "doe" }).success(function(response) {
console.log("success");
}).error(function(err){
console.log("failure")
});
Please note that Params are used as URL parameters; something like this:
app.get('/addUser/:userID', function(req, res) {
console.log(req.params.userID);
});

Categories