Anyone familiar with Express Router can point me what's wrong here? [SOLVED]

I’m writing up an API as part of a tutorial. My GET and DELETE processes work fine, but anything that requires parsed JSON doesn’t seem to be working.

Here’s my server:

var express = require('express');
var morgan = require('morgan');


var dishRouter = require('./dishRouter');
var promoRouter = require('./promoRouter');
var leaderRouter = require('./leaderRouter');

var hostname = 'localhost';
var port = 3000;

var app = express();


app.use(morgan('dev'));


app.use(express.static(__dirname + '/public'));
app.use('/dishes', dishRouter);
app.use('/promotions', promoRouter);
app.use('/leadership', leaderRouter);

app.listen(port, hostname, function() {
  console.log(`Server running at http://${hostname}:${port}/`);
});

All three of my modules are exactly the same minus that they use different terminology in their returned strings. For example, here is promoRouter.js:


var express = require('express');
var bodyParser = require('body-parser');

var promoRouter = express.Router();
promoRouter.use(bodyParser.json());
  
promoRouter.route('/')
        .all(function(request, response, next) {
          response.writeHead(200, {'Content-Type': 'text/plain'});
          next();
        })
        .get(function(request, response, next) {
          response.end('Will send all the promos to you!');
        })
        .post(function(request, response, next) {
          response.end('Will add the promo: ' + request.body.name + ' with details: ' + request.body.description);
        })
        .delete(function(request, response, next) {
          response.end('Deleting all promos');
        });

promoRouter.route('/:promoId')
        .all(function(request, response, next) {
          response.writeHead(200, {'Content-Type': 'text/plain'});
          next();
        })
        .get(function(request, response, next) {
          response.end('Will send details of the promo: ' + request.params.promoId + ' to you!');
        })
        .put(function(request, response, next) {
          response.write('Updating the promo: ' + request.params.promoId + '\n');
          response.end('Will update the promo: ' + request.body.name + ' with details: ' + request.body.description);
        })
        .delete(function(request, response, next) {
          response.end('Deleting promo: ' + request.params.promoId);
        });

module.exports = promoRouter;

When I test my POST and PUT commands using Postman, I get a string with undefined in place of where I should be seeing request.body.name and request.body.description:

Will add the promo: undefined with details: undefined

So I’m leaning toward that I’ve misused body-parser somehow as that is supposed to parse out the JSON in the request so that each part is available for my response to the client. I’ve double checked and body-parser does exist in my node_modules folder.

How about bodyParser.urlencoded({ extended: false });? I honestly don’t know much about body-parser, but all examples I’ve seen that use post use it.

It could be because you use Contet-Type as text/plain. Could you please change it to application/json and try.

I think Kev is right - you do need to call a specific body parser method, not just require it.

Also, see this post for possible security issues when you use body parser:

You should be ok, but worth being aware off and understanding.

Tried this and it returns another set of errors.

Adjusted my server code to include

app.use(bodyParser.json());
bodyParser.urlencoded({ extended: false });

and removed it from the modules, but still no dice. Still getting the same errors.

You need to use it just like you do with the json version - app.use(bodyParser.urlencoded({ extended: true/false }));.

Extended should be set to true or false depending on what you want/need.

If you’re not using HTML forms to send the data though, I’m not sure this should be the issue?

Made that change and still getting same results:

Will add the promo: undefined with details: undefined

All the data is hard coded in as all I’m passing is a string with some parsed json data from the request to the console.

Hmm. Just to be clear: request.body is not undefined, but the properties themselves are?

Looks like it. If I ask it to send just request.body in the response I get:

Will add the dish: [object Object] with details: [object Object]

What does the req.body object look like? (Try console logging it and see what properties are on it.) If there’s no name or description property at all, then you’ll need to figure out why those aren’t being set. (In Postman, are the keys that you’re entering “name” and “description”, without any actual quotes around it?)

Postman can be weird/annoying about the quotes - I think it might want double quotes around your value, if you’re sending it via form-data. I’d have to play around with the other options to see what specifically it wants if you’re sending it via any other option.

I’m sending the request in Postman as raw data and here is my object. I’ve tried with both single and double quotes in the JSON.

{"name":"example name", "description":"new description"}

On a POST request, I have it console.logging:

console.log(request.body) outputs {}
console.log(request.body.name) outputs undefined
console.log(request.body.description) outputs undefined

The second two obviously make sense if the object is empty. I’m leaning more and more toward this being an issue with Postman. I’ve even checked the official solution and ran it on my machine and I get this same issue. My package.json file includes all three of the required modules: express, morgan, and body-parser and all three of them are in my node_modules folder in the same directory as my server.js file.

If I include this line in my server.js file:

app.use(bodyParser.urlencoded({ extended: false })); and then send the data from Postman as x-www-form-urlencoded, then it works as expected.

Just joking guys, in Postman I was sending my JSON object as raw text and not as JSON, so it didn’t know how to handle it.

2 Likes

Nice solution. Anything related to router IP address, login, username, password can be found here: 192.168.0.1 https://19216801help.com

I don’t get it, you are programing the router or you are trying to make a server. Because I don’t understand what is the meaning of what you have wrote. I know that a friend of mine was trying to improve his router with the help of a program, it was for Xfinity router, he were using an example https://www.router-reset.com/default-ip-address-list/Xfinity , and it helped him a lot. His program worked and everything was fine, it was a success.

You got it a little wrong and right mate. But thank for sharing anyway.