Last updated: Apr 5, 2024
Reading timeยท5 min
The req.body
property is undefined in Express.js when you forget to set the
body-parser
middleware before you register your route handler function.
To resolve the issue, register the bodyParser.json()
middleware above the code
that registers your route handlers.
Here is an example of how the issue is caused.
import express from 'express'; // ๐๏ธ If you use CommonJS require() // const express = require('express'); const app = express(); // โ๏ธ Forgot to register body-parser middleware app.post('/login', function (req, res) { // โ๏ธ req.body is undefined here console.log('req.body: ', req.body); res.send('bobbyhadz.com'); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
If I start the Express.js server with npx nodemon index.js
:
npx nodemon index.js
And make a POST request to http://localhost:5000/login
, the value of
req.body
will be undefined
.
Here is a screenshot of making the POST request using Postman.
You can also use curl to issue the HTTP POST request.
curl --location 'http://localhost:5000/login' \ --header 'Content-Type: application/json' \ --data '{ "username": "bobbyhadz", "password": "123" }'
If I look at my terminal, the value of req.body
is undefined
.
bodyParser
middleware to resolve the issueTo resolve the issue:
Open your terminal in your project's root directory (where your package.json
file is) and run the following command.
# install with NPM npm install body-parser # or install with YARN yarn add body-parser
bodyParser
middleware above the code that registers your route
handlers.import express from 'express'; import bodyParser from 'body-parser'; // ๐๏ธ if you use CommonJS require() // const express = require('express'); // const bodyParser = require('body-parser'); const app = express(); // โ Register the `bodyParser` middleware here app.use(bodyParser.json()); app.use( bodyParser.urlencoded({ extended: true, }), ); app.post('/login', function (req, res) { // โ req.body is an object here console.log('req.body: ', req.body); console.log( `username: ${req.body.username}, password: ${req.body.password}`, ); res.send( `username: ${req.body.username}, password: ${req.body.password}`, ); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
Restart your Express.js development server by issuing the following command.
npx nodemon index.js
The body-parser
module enables us to parse incoming request bodies in a
middleware.
Note that the following 2 app.use()
calls must be at the top of your file,
before registering any route handlers.
const app = express(); // โ Register the `bodyParser` middleware here app.use(bodyParser.json()); app.use( bodyParser.urlencoded({ extended: true, }), );
If you place the app.use()
calls after registering a route handler, req.body
will be undefined
.
Rerun the POST request to http://localhost:5000/login
and notice that the
value of req.body
is an object that contains the key-value pairs that you've
sent over the network.
Note: when you make a POST request with JSON data, make sure to set the
"Content-Type"
request header to"application/json"
.
Your Express.js server needs to know what type of data you're sending over the network, so it knows how to parse it.
Commonly used values of the Content-Type
header include:
application/json
application/x-www-form-urlencoded
If I switch to my terminal where the Express.js server is run, I can see that
the value of req.body
is no longer undefined
.
The shape of the req.body
object is based on user-controlled input.
The request body in my POST request has the username
and password
properties, so these are the properties that we can access on the req.body
object.
app.post('/login', function (req, res) { console.log('req.body: ', req.body); console.log( `username: ${req.body.username}, password: ${req.body.password}`, ); res.send( `username: ${req.body.username}, password: ${req.body.password}`, ); });
You can also use curl to issue the HTTP POST request.
curl --location 'http://localhost:5000/login' \ --header 'Content-Type: application/json' \ --data '{ "username": "bobbyhadz", "password": "123" }'
Notice that the Content-Type
header is set to application/json
, so
Express.js knows we're sending JSON data over the network.
If you use an Express.js version that is greater than 4.16.0
, you don't have
to import and register the bodyParser
middleware as it is built into Express.
import express from 'express'; // ๐๏ธ If you use CommonJS require() // const express = require('express'); const app = express(); // โ Register the body parsing middleware here app.use(express.json()); app.use( express.urlencoded({ extended: true, }), ); app.post('/login', function (req, res) { console.log('req.body: ', req.body); console.log( `username: ${req.body.username}, password: ${req.body.password}`, ); res.send( `username: ${req.body.username}, password: ${req.body.password}`, ); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
The code sample above achieves the same result, however, notice that we didn't
use the body-parser
module at all.
// โ Register the body parsing middleware here app.use(express.json()); app.use( express.urlencoded({ extended: true, }), );
Instead, we used express.json()
and express.urlencoded()
.
The examples above register the application/json
and
application/x-www-form-urlencoded
parsing middlewares for all routes.
You could also register a middleware for a specific route.
Here is an example that registers the JSON parsing middleware for a single route only.
import express from 'express'; // ๐๏ธ If you use CommonJS require() // const express = require('express'); const app = express(); // ๐๏ธ Only registers JSON parsing middleware for this route app.post('/login', express.json(), function (req, res) { console.log('req.body: ', req.body); res.send( `username: ${req.body.username}, password: ${req.body.password}`, ); }); const port = 5000; app.listen(port, () => { console.log(`Example app listening on port ${port}`); });
If you decide to use this approach, you'd have to manually register the parsing middleware for each route.
The same can be done for application/x-www-form-urlencoded
requests.
app.post( '/login', express.urlencoded({extended: true}), (req, res) => { // ... }, );
However, it is usually much easier to simply register the parsing middlewares globally as we did in the previous examples.
By default, Express.js doesn't read the request body of a POST/PUT or PATCH requests.
Instead, you have to register a middleware that runs before your route handler and parses the body.
Registering the body-parser
middleware before your route handlers resolves the
issue and populates the req.body
object based on the data the user sent over
the network.
app.use(bodyParser.json()); app.use( bodyParser.urlencoded({ extended: true, }), );
You can learn more about the related topics by checking out the following tutorials: