5

I've looked through quite a bit of other posts and I'm very lost with this.

I can run a console.log(req) and get the following output

ServerResponse {
  ...
  req: 
   IncomingMessage {
    ...
     url: '/my-endpoint',
     method: 'POST',
     statusCode: null,
     statusMessage: null,
     ...
     body: { foo: 'bar' },
     _body: true,
     ...
     route: Route { path: '/my-endpoint', stack: [Object], methods: [Object] } },
  ...

Looks solid, so I would expect to do console.log(req.body) and get { foo: 'bar' } back in the console...but nope, getting undefined

After research, I found that it may be something with my app.js file and specifically with a body-parser, however, I have all of that already

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var http = require('http');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

//Home Page Rendering
var index = require('./routes/index');
app.use('/', index);

// All other routes are kept in the `routes` module
require('./routes')(app);

module.exports = app;

routes.js

module.exports = function routing(app) {
  var apiClient = require('./services/apiClient');

  app.post('/get-device-info', function(err, req, res){
    console.log("/get-device-info routes");
    apiClient(req, res);
  });
};

apiClient.js

module.exports = function callApi(req, res){
  console.log(req);
  console.log(req.body)
};

index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

module.exports = router;

Here's what I've tried

app.use(express.bodyParser());

Ensuring that the incoming request is explicitly declaring application/json

Declaring body parser.json in other ways

Adding a config function

peteb
  • 18,552
  • 9
  • 50
  • 62
Lucas Crostarosa
  • 1,192
  • 6
  • 13
  • 26
  • Which version of Express are you using? You may wish to stick to 4.x and the separate `body-parser` module, never `express.bodyParser`. Can you also include the index route function? – E_net4 Apr 11 '17 at 18:19
  • he does stick to separate body-parser... – Jakub Pastuszuk Apr 11 '17 at 18:33
  • I'm not sure why I'm being downvoted on this. Added more code to the OP. I am using node 7.4.0 and express 4.15.0 – Lucas Crostarosa Apr 11 '17 at 18:47
  • Please include request headers being sent to the server before the server processes them. (network tab of browser) – Kevin B Apr 11 '17 at 18:49

2 Answers2

5

Your problem is that Express doesn't use error first callbacks for its route handlers. The below code won't work because the app.post handler doesn't have the signature (req, res) => {}. In the below code err is equal to req, req is equal to res, and res is equal to next.

// routes.js
module.exports = function routing(app) {
  var apiClient = require('./services/apiClient');

  app.post('/get-device-info', function(err, req, res){
    console.log("/get-device-info routes");

    // Assuming the request is correct 
    // the value of body will be the request body  
    console.log(res.body)

    apiClient(req, res);
  });
};`

There are 3 different route callback signatures you can use in Express

  • (req, res) => {} - This is the most basic and defines a route that just cares about the request and response
  • (req, res, next) => {} - This is middleware callback signature which looks like a basic route callback but, it also assigns the next object which tells Express to call the next matching route.
  • (err, req, res, next) => {} - This is the error handling route callback and you only need 1 per Express Router Middleware or Express App. It gets called if next(err) is called within a Route or Middleware. More specifically, if next() isn't called with a string or nothing it will skip all remaining Middleware and Routes and go straight to the error handler. You can read more about it in the Express Docs

You'll need to change the route definition to

app.post('/get-device-info', (req, res) => {
  apiClient(req, res)
})

Or you could even do this

module.exports = app => {
  let apiClient = require('./services/apiClient')

  app.post('/get-device-info', apiClient)
}
peteb
  • 18,552
  • 9
  • 50
  • 62
1

Try this, since it worked for me.

First declare app and then the bodyParser, since bodyParser is used within app:

const app           = express();
const bodyParser    = require('body-parser');

Then have these lines below:

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: true}))
Greenonline
  • 1,330
  • 8
  • 23
  • 31
JVK
  • 11
  • 3