34

I'm working on an API with NodeJS and Express (and more stuff like mongo, sockets, etc) but i'm stuck on a very simple step I believe. I'm just trying to get the information from the POST req object, but I get an error when trying to access req.body

Here's what I have:

var express     = require('express'),
    http        = require('http'),
    path        = require('path'),
    fs          = require('fs'),
    io          = require('socket.io');
    dynroute    = require('dynroute');

var app = express();
app.set('port', process.env.PORT || 3999);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(app.router);
app.use(express.bodyParser());

app.post('/user', function(req, res) {

    console.log(JSON.stringify(req.body));
    res.send(req.body.self);
});

http.createServer(app).listen(app.get('port'), function ()
{
    console.log('App Server is now running at:' + app.get('port'));     
});

On the console.log(JSON.stringify(req.body)); I get undefined and on the res.send(req.body.self); I get TypeError: Cannot read property 'self' of undefined

I've been seaching for this type of error and usually the issue is that people do not include app.use(express.bodyParser()); middleware , so I also tried using app.use(express.urlencoded()); and app.use(express.json());, which didn't work either.

If I do a console.log(req) I can see the entire object but I do not get to see body or any of the content I'm passing when doing the POST request from a client (I'm passing it as JSON).

**I know I could use restify or sails.js to build APIs within Node but i want to do everything myself so I can learn from the experience.*

Thanks

EDIT: I had to put the bodyparser middleware before the app.router middleware, that fixed it!

Shark Lasers
  • 441
  • 6
  • 15
kevinblanco
  • 779
  • 2
  • 7
  • 13
  • I would suggest posting information about how you're making the post request. If 'body' isn't being picked up by the req object then my first thought would be that the post request hasn't been successful. – Michael Dec 04 '13 at 16:49
  • I'm using a Chrome App called Advanced Rest Client , i'm just doing a POST request to my URL passing `['user':'kevinblanco']` as the content with application/json as the content type header. – kevinblanco Dec 04 '13 at 16:53
  • I wish there was a single version number of express, node, whatever indicated in this question (and its answers). I reckon it is now obsolete, because a problem like this hit me today, but only when the remote server returns status code 4xx. Express 4.13.1. BodyParser 1.13.2. And the accepted answer won't help. – Marco Faustinelli Jan 06 '16 at 20:48

10 Answers10

41

Move the bodyParser middleware above the router middleware!

var app = express();
app.set('port', process.env.PORT || 3999);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(app.router);
Renato Gama
  • 16,431
  • 12
  • 58
  • 92
18

Content-Type = "application/json" should be one of the Request Headers

Aakash
  • 21,375
  • 7
  • 100
  • 81
  • 1
    I don't know why you had a downvote.. Express 4.0 comes with all of the fixes listed above your comment so they were useless. While using a REST testing extension you MUST assign a Content-Type. Awesome stuff :) – Alex Boisselle Apr 29 '16 at 23:12
  • 2
    This turned out to be the case for me as well as using native fetch API in Google Chrome doesn't default content-type header to application/json so no body parsing ever occurred server side as incoming request must have been interpreted as text. – A-Dubb Jul 18 '17 at 14:49
5

BodyParser is no longer bundled with Express

npm install body-parser
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
Tobias Artz
  • 51
  • 1
  • 2
  • 3
    for parsing json bodies, add the following line: `app.use(bodyParser.json())` – Camilo Silva Nov 08 '15 at 02:53
  • As of jan '16 bug is still somewhere there. I am using Express 4.13.1. BodyParser 1.13.2. Only when status code is 4xx I cannot get the body: rendering of the error page fails and node server explodes. When status code is 2xx, no problem. Tried all solutions proposed in this page. That's weird! – Marco Faustinelli Jan 06 '16 at 20:51
  • I am using this with express 4.16.4 version this is not working for me app.use(bodyParser.urlencoded({extended: true})) app.use(bodyParser.json()) app.post('/user_create',(req,res)=>{ console.log("trying to create a user"); const firstName = req.body.create_first_name const lastName = req.body.create_last_name console.log("first name is "+firstName+" "+lastName); res.end() }) – Vivek Pratap Singh Feb 20 '19 at 20:01
1

For me @kevinblanco's note of "I had to put the bodyparser middleware before the app.router middleware, that fix it!" did it for me. Putting it in a separate answer since its buried at the bottom.

Your code will need to look something like this:

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// My routing here
Ash Blue
  • 5,344
  • 5
  • 30
  • 36
1

Most of the above-listed answers are right but at present [28-July-2020] the most suitable one is to use inbuilt's of express i.e:

app.use(express.json());

This will act as a middleware to accept the incoming JSON object in your request's

vishnu.dev
  • 11
  • 2
1

in my case I have to add these two line to read post request body

app.use(express.json());

// add this middleware to read post request body
app.use(express.text());
Wisnu Wijokangko
  • 1,482
  • 1
  • 13
  • 15
0

In Golang, you can set Content-Type as application/json before doing POST http client request to nodejs express router:

//Golang
import (    
    "bytes"
    "encoding/json"
    "errors"    
    "net/http"      
)

//method := "POST"
//url := "http://ip:port/api/router"

func request(method string, url string, data interface{}, pHeader map[string]string) {
    pBody, err := json.Marshal(data)
    if err != nil {
        return []byte{}, err
    }
    request, err = http.NewRequest(method, url, bytes.NewBuffer(pBody))
    if(err!=nil ){
        return []byte{}, err
    }
    request.Header.Set("Content-Type", "application/json")

    //add header params if any
    for key, head := range pHeader {
        request.Header.Add(key, head)
    }

    client := &http.Client{}
    resp, err := client.Do(request)
    if err != nil {
       return []byte{}, err
    }
    defer resp.Body.Close() 
}

//NODEJS

//app.js
var express = require('express');
...

var app = express();
app.use(express.json());


var router= require('path/to/router.js');
//use the router
app.use('/api', router);
...

//router.js    
router.post('/router', function (req, res, next) {
    //log request body to view its values of incoming request
    console.log('req.body', req.body)
})
Yudi Tjhia
  • 1
  • 1
  • 2
0

Express has an inbuilt method for recognizing JSON objects from POST requests coming from the client end. Instead of using body-parser you can use this in your index.js file:

app.use(express.json());

Sebastian Gomes
  • 775
  • 9
  • 12
0

You must install bodyParser and then use it on your app like this:

// middlewares
app.use(bodyParser.json());
app.use(sucursalRoutes);
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

Hope this have helped you.

0

You don't need bodyParser. Simply add the following lines -

app.use(express.urlencoded({ extended: true }));
app.use(express.json());
Abhinav Manchanda
  • 6,546
  • 3
  • 39
  • 46