Passing the params using react fetch not working - javascript

Here's the server controller (which works)
function logTheRequest(req, res) {
console.log(req.body);
res.sendStatus(200);
}
Here's the client side fetch
newCustomer() {
fetch('/customers/sign-up', {
method: 'POST',
body: 'test',
});
}
But when I console.log(req.body), all I get is { }

req.body kept coming back empty for me until I added app.use(bodyParser.json() into my server.js file. Make sure you import body-parser.
Looks like the reason is because bodyParser parses request bodies in middleware under req.body: https://github.com/expressjs/body-parser. More details on bodyParser: What does `app.use(bodyParser.json())` do?.

Related

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}));

Send POST data with raw json with postman Express

I'm trying to log all the data and then return it as a response.
app.post('/data', (req, res) => {
const data = req.body
console.log(data)
return res.json({
data
})
})
I'm sending data with Postman. In the Body tab I have "raw" selected and "JSON (application/json)". Headers tab is Content-Type application/json. I'm sending this:
{
"aa": 23
}
When I click send button all I get is an empty object and the data variable is undefined in my console.log. How to fix it? I double checked everything. It should work, but it doesn't.
It seems like you're passing an invalid value to res.JSON(). Try:
return res.json(data);
Alright, I found the solution.
"As body-parser module is used to parse the body and urls, it should be called before any call to 'req.body...'."
So I did this:
import bodyParser from 'body-parser'
const app = express()
app.use(bodyParser.urlencoded())
app.use(bodyParser.json())
app.post('/data', (req, res) => {
const data = req.body
console.log(data)
return res.json({
data
})
})
And now it works fine.

Express.js + body-parser: empty req.body from POST request

I am using Express and body-parser middleware to process incoming requests. On the front end, I have a form that's just a hidden input and a submit button (written in Pug):
form(notes="saveNotesForm" action=`/lessons/${lesson._id}/notes` method="POST" enctype="application/x-www-form-urlencoded")
input(type="hidden" id="hiddenNotes" name="hiddenNotes" alt="Notes Copy" value="test").notesHidden
input(type="submit" name="saveNotes" alt="Save Notes" value="Save")
On the backend, I have the Express app using body-parser:
const bodyParser = require('body-parser');
// ...
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
And the route processing the incoming request:
router.post('/lessons/:lessonID/notes', lessonController.updateNotes);
// ... and in lessonController:
exports.updateNotes = async (req, res) => {
console.log('updateNotes request received');
console.log(req.body);
res.status(200).json({ status: 'success' });
}
When I try to use req.body in updateNotes, the body is an empty object, but should at least have the property hiddenNotes with the value "test". Please comment if you have any questions or think you see the problem!
[UPDATED]
This was a silly mistake, I forgot I had written a separate event handler for when this form gets submitted - it just took me posting on SO before I went through all of my code :) The event handler uses axios and looks like this:
const SaveNotesButton = $('form.saveNotes');
SaveNotesButton.on('submit', ajaxSaveNotes);
function ajaxSaveNotes(e) {
e.preventDefault();
axios
.post(this.action)
.then(res => {
console.log(res.data);
})
.catch(console.error);
}
Unfortunately, when making posts with axios, you need to include the data in an object like this, or else it won't be included in the request:
const SaveNotesButton = $('form.saveNotes');
SaveNotesButton.on('submit', ajaxSaveNotes);
function ajaxSaveNotes(e) {
e.preventDefault();
axios
.post(this.action, { notes: this.children.hiddenNotes.value }) // Data added here
.then(res => {
console.log(res.data);
})
.catch(console.error);
}
Have to tried querying your end point using Postman or something similar?
There could be one possible explanation for why your req.body is undefined. Are you sure your app.use(bodyParser.json()) and app.use(bodyParser.url... are written before your app.use('***', router) lines? If you put the body parser middleware AFTER your router middleware it essentially won't get called because middleware are called in the order they are put in app.use. So you should place your bodyParser before all your router logic. BodyParser middleware then calls all the other middleware (with the req.body populated) that come after it including all your router level middleware.
Hope it helps!
Not sure how you are defining your routes but I would expect a post route to look like the following:
const express = require('express');
const app = express();
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
app.post('/lessons/:lessonID/notes', (req, res) => {
// now pass the req object to your function
lessonController.updateNotes(req);
});
You need to pass the req object to your function to be able to access req.body...

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