req.body is undefined in Express.js & Node issue [Solved]

avatar
Borislav Hadzhiev

Last updated: Apr 5, 2024
5 min

banner

# req.body is undefined in Express.js & Node issue [Solved]

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.

req body undefined in express

Here is an example of how the issue is caused.

index.js
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:

shell
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.

making post request using postman

You can also use curl to issue the HTTP POST request.

shell
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.

req body undefined in express

# Register the bodyParser middleware to resolve the issue

To resolve the issue:

  1. Make sure you have the body-parser module installed.

Open your terminal in your project's root directory (where your package.json file is) and run the following command.

shell
# install with NPM npm install body-parser # or install with YARN yarn add body-parser

install body parser module

  1. Register the bodyParser middleware above the code that registers your route handlers.
index.js
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}`); });
The code for this article is available on GitHub

Restart your Express.js development server by issuing the following command.

shell
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.

index.js
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.

rerun post request using postman

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.

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.

index.js
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}`, ); });
The code for this article is available on GitHub

You can also use curl to issue the HTTP POST request.

shell
curl --location 'http://localhost:5000/login' \ --header 'Content-Type: application/json' \ --data '{ "username": "bobbyhadz", "password": "123" }'

make http post request using curl

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.

index.js
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 for this article is available on GitHub

The code sample above achieves the same result, however, notice that we didn't use the body-parser module at all.

index.js
// โœ… 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.

index.js
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}`); });
The code for this article is available on GitHub

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.

index.js
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.

# Conclusion

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.

index.js
app.use(bodyParser.json()); app.use( bodyParser.urlencoded({ extended: true, }), );

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev