I try to use Postman for generating some post transaction of my web but when I check the post method of my code it print the empty {} and add the empty {} to my list. I try to use middleware but the problem is still occurring.
This is my code.
// my code at restaurant.js
const express = require("express");
const router = express.Router();
const restaurants = require("../data")
router.get("/",(req,res) =>{
res.json(restaurants);
}
)
router.get("/:id",(req,res) =>{
const restaurantid = Number.parseInt(req.params.id,10);
const restaurant = restaurants.find((restaurant) => restaurant.id === restaurantid);
res.json(restaurant);
})
router.post("/",(req,res)=>{
console.log(req.body);
new_restaurant = req.body;
restaurants.push(new_restaurant);
res.json(new_restaurant);
}
)
module.exports = router;
//my code at index.js
const express = require("express");
const app = express();
const router = express.Router();
const restaurantsRouter = require("./routes/restaurants.js");
// Middleware
app.use(express.json());
app.use(express.urlencoded({extended:false}));
// Routes
app.use("/apis/restaurants",restaurantsRouter);
app.get("/",(req,res)=>{
res.send("<h1>Hello Express</h1>");
});
app.listen(3000,()=> {
console.log("Listening to port 3000");
})
module.exports = router;
The general reasons for an empty req.body on an incoming POST request are as follows:
You are failing to send the body properly with whatever client is sending the request.
You are failing to set the right content-type with the request that matches the type of the body data you are sending. If you're sending JSON, then you will need to make sure the incoming request has the content-type application/json.
You don't have the right middleware installed or working properly that will match the incoming content-type, read the body from the incoming stream, parse it and put the parsed results in req.body.
The middleware for parsing that content-type is not registered before your route handler in Express.
Some other middleware is "eating" the body before your middleware so the body is empty when it gets to your JSON middleware.
So, you will need to go through your POST request and eliminate each of these possibilities until you find the problem.
Related
Basically, I am using Thunder Client to send the requests and I am using the post request. The failure that I am facing is that whenever I send the request and also send the body contents and have already used content-type application/json in the header and when at the request portion I try to get req.body it returns undefined. I don't know why this error is occurring. Could someone please help?
const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const Admin = require('../Models/Admin');
//Route 1 : Create an ADMIN Account
router.post('/createadmin', async (req, res)=>{
console.log(req.body)
res.json(req.body)
})
module.exports = router
This is a bit late so hopefully you figured it out by now, but you may need to install and then use body parser. So npm i body-parser...then you can use it as necessary demonstrated here:
My main server.js File
const koa = require("koa");
const Router = require("koa-router");
const bodyParser = require("koa-bodyparser");
const app = new koa();
var router = new Router();
// app.use(bodyParser({ enableTypes: ["json", "text"] }));
// I have also tried passing enabletypes parameteres but it still is not working..
app.use(bodyParser());
app.use(router.routes());
app.use(router.allowedMethods());
router.post("/", async (ctx) => {
console.log(ctx);
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => console.log(`Server started on port no ${PORT}`));
When i hit this router.post("/") end point ... just for the purpose to see my context object i console logged the context object and it shows the following in the console when I hit this endpoint using postman (i am send JSON body in the request)
My postman request
How do I access my body (JSON object) ?
To access your body object, try the following:
const body = ctx.request.body;
Secondly: because in one of the comments there was a note, why you get a 404. I guess this is because in your route you are not returning anything. So your route could look like:
router.post("/", async (ctx) => {
const body = ctx.request.body;
console.log(body);
return (true) // or whatever you want to return to the client
});
I'd suggest using something to return i.e. if you return nothing you are going to get a 404 with Koa. Just set the body of the ctx i.e. ctx.body="something here".
Other than that depending on what you are using in the app to hit it Postman may work slightly different and pass additional headers etc. I've run into this a handful of times using Thunder Client on VS Code where it works when poking it but in the app something is slightly off. I've ONLY run into this with Koa and never express so might be worth checking and logging along the way WITHIN the app.
I cannot seem to get the body data shown on my server. I am actually trying to get this in post/put/fetch calls, but to try to fix the problem, i've boiled it down to a simple .get, and it still won't appear. Can anyone see why the body isn't showing on the server? I'm unable to get anything done in more complicated called due to this (like get the body of the req, but sticking to this simple example for now.)
This code is a fully working and sends data, just cant seem to access the body on the server.
server.js
const express = require('express');
const app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
const port = process.env.PORT || 8000;
const Cat = require('./Cat');
const Dog = require('./Dog');
app.route('/animals')
.get(function (req, res) {
console.log(req.body, 'req.body log'); //this returns {}
res.send({ Cat, Dog });
})
app.listen(port, () => console.log(`Listening on port ${port}`));
In react, if I call the following callApi() function, console.log shows the body data just fine on the front end, and the data can be used on the page.
client call
callApi = async () => {
const response = await fetch('/animals');
const body = await response.json();
console.log(body) //shows all the data just fine!
if (response.status !== 200) throw Error(body.message);
return body;
};
Using node 9 and express 4.
I think you're confusing the request and response objects. But aside from that, I'll explain where/how to get data passed in from GET and POST/PUT requests.
When a GET request is made, you can pass data to the server via query params (i.e. /animals?type=cat). These parameters will be available already parsed in an object called req.query.
When a POST or PUT request is made, and you've applied the body parsing middleware (which you have done), the JSON will be available as a parsed object under req.body.
In your example, you have made a GET request, and have no provided any query string parameters. So req.body will return an empty object, as will req.query.
Your client call shows data because you've sent data back in the response via res.send(). This is totally unrelated to why req.body is an empty object in your case.
Try using fetch('/animals?type=cat') in your client call. Then, you will see that req.query returns { type: 'cat' }.
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...
I have a node.js + Express application. It has a webhook that I have provided to a third party service. The service sends a POST request to my webhook with JSON body which looks something like this:
{"split_info" : "null", "customerName" : "Merchant Name",
"additionalCharges" : "null", "paymentMode":"CC",
"hash":"a31ff1b91fd9b8ae9c82f38b02348d21fsdfd86cc828ac9a0acf82050996372cc656de3db0fe3bf9af52b73a182a77787241f3e19ec893391607301b03e70db8",
"status" : "Release Payment", "paymentId" : "551731" ,
"productInfo":"productInfo", "customerEmail":"test#gmail.com",
"customerPhone":"9876543212", "merchantTransactionId":"jnn",
"amount":"100.0", "udf2":"null", "notificationId" :"4", "udf1":"null",
"udf5":"null", "udf4":"null", "udf3":"null","error_Message":"No
Error"}
I am using body-parser module to read POST data. However when I do req.body it gives [object Object], if I do JSON.stringify(req.body), it gives {} i.e. empty. If I try to access the keys in the response like req.body.paymentMode then it gives undefined.
Here is my router code for the webhook: mywebhook.js
var express = require('express');
var router = express.Router();
router.post('/success', function(req, res){
//this is where I need to strip the JSON request
//req.body or JSON.stringify(req.body) or anything that works
//if everything is okay then I send
res.sendStatus(200);
});
module.exports = router;
My app.js looks like this:
var express = require('express');
var exphbs = require('express-handlebars');
var router = express.Router();
var bodyParser = require('body-parser');
var mywebhook = require('./routes/mywebhook');
var app = express();
.
.
.
app.use(bodyParser.urlencoded({'extended':'true'})); // parse application/x-www-form-urlencoded
app.use(bodyParser.json()); // parse application/json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
app.use('/callwebhook', mywebhook);
.
.
.
so on
Pretty sure I am missing something or doing something wrong, but I am not able to figure it out.
Thanks.
I finally found what was going on.
The way the body-parser works is that it will only try to parse a request in which they understand the Content-Type. This is mainly so you can stack them (app.use multiple parser types without conflict) and also because you typically don't want to parse a request that's going to fail (Content-Type: text/html is unlikely to ever get through a JSON.parse, for example).
I ended up getting sent */*; charset=UTF-8 which is not even a valid Content-Type header value period. The body-parser module refused to accept it, since that is gibberish. This module does allow you to setup a function that lets you put any custom logic you want to perform the filtering.
I had to put the body parser in my router code just for this webhook case.
var bodyParser = require('body-parser');
var customParser = bodyParser.json({type: function(req) {
return req.headers['content-type'] === '*/*; charset=UTF-8';
}});
router.post('/success', customParser, function(req, res){
console.log(JSON.stringify(req.body));
});
#svens thank you for your help.