req.body returns undefined - nodejs - node.js

When I put app.use(bodyParser.json()); below app.use('/api', require('./routes/api'))
req.body returns undefined. But if I put app.use(bodyParser.json()); above app.use('/api', require('./routes/api')); it returns correctly. So the question is why?
Here is my code:
index.js file
const express = require('express');
const app = express();
const bodyParser= require('body-parser');
app.use(bodyParser.json());
app.use('/api', require('./routes/api'));
app.listen(process.env.port || 3000, function(){
console.log('You are listening to port 3000');
});
api.js file
const express= require('express');
const router= express.Router();
router.get('/ninjas', function(req, res){
res.send({type: 'GET'});
});
router.post('/ninjas', function(req, res){
console.log(req.body);
res.send({type: 'POST'});
});
router.put('/ninjas/:id', function(req, res){
res.send({type: 'PUT'});
});
router.delete('/ninjas/:id', function(req, res){
res.send({type: 'DELETE'});
});
module.exports =router;
Thanks in advance!

We need body-parser middleware to read from req.body,
In Javascript code executes line by line (for non IO operations).
So when you place app.use(bodyParser.json()) after requiring your router file logic, body-parser is not invoked and plugged, so you need to invoke it before any other logic, so that you can read from the request.

Bodyparser is a middleware which should run everytime when a route is accessed.
A middleware (like bodyparser) is written like this
const middleware = (req, res, next) => {
//some code here
next();
}
The next function starts the execution of another middleware function
So when you use the bodyparser middleware after the routes req.body will not be initialized because the bodyparser middleware never ran for the route and the response ends with the res.send().
But if you use the bodyparser middleware before initializing the routes the bodyparser middleware will always run.
You can see more examples on middleware in the expressjs docs
https://expressjs.com/en/guide/using-middleware.html

Related

Node js: getting an error Cannot GET /route when i use get method

When I use the "use" method my code works fine, but when I use the "get" it gives an error: "Cannot GET /route1".
My Code:
const express = require('express');
const app = express();
const expbs = require('express-handlebars');
const path = require('path');
const routes = require('./routes/handlers');
app.use(express.static('public'));
const hbs = expbs.create({
defaultLayout: 'main',
layoutsDir: path.join(__dirname, 'views/mainLayout'),
partialsDir: path.join(__dirname, 'views/pieces'),
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
app.get('/route1', routes);
app.listen(8080, () => {
console.log('Server is starting at port ', 8080);
});
I am new to node js, please tell me can i define routes with "get" method.
I believe your routes/handlers.js look something like this
var express = require('express');
var router = express.Router();
function greetUser(req, res){
res.send("Welcome dear user");
}
router.get("/", greetUser);
router.post("/", (req, res)=>{ res.send("user registered") });
module.exports = router
The problem here is this last line, this router object which is being exported works fine for app.use middleware, while .get or .post expects 2nd parameter to be a function
If you export this greetUser function from your router as well or receive this function from anywhere, this should start functioning well. Practically it would be
app.get("/route1", (req, res)=>{ res.send({status : true, message : "sample JSON"})})
If you are using router you coudn't use get method.
Here is the docs.
Only the handler has access to get method. app.use will add path to api route which point to get,post and etc.
You could only explicitly define a get as a standalone get route.
app.get('/route1', (req, res) => {
res.send("You have hit route1 - get");
});
When using router you could only include the router object as a parameter in app.use(path, routerObj) method.
app.get('/route1', routes);
woulde be app.use('/route1', routes);

POST request returns undefined

When the request from postman initiated with the json as given below, I get hello undefined as response.
request json
{
"name":"test"
}
my middleware
import express from 'express';
import bodyParser from 'body-parser';
const app = express();
app.use(bodyParser.json());
app.get('/hello', (req, res)=>{
return res.send("hello");
});
app.post('/hello', (req, res)=>{
console.log(req.body);
return res.send(`hello ${req.body.name}`);
})
app.listen(8000, () => console.log('listening on port 8000'));
started the server with following command
npx babel-node src/server.js
Since express 4.16.0 you can use app.use(express.json()); to get the json data from request,in your case it would be.You don't require to use bodyparser and all.
const app = express();
app.use(bodyParser.json()); // remove this
app.use(express.json())// add this line
Actually issue is not with the code. The Postman client making the request didn't mark it as application/json type request. Once I rectified it, it just worked as expected.
use bodyParser as meddleware
const app = express();
app.use(bodyParser.urlencoded({ extended: true })); //add this
app.use(bodyParser.json());
also
app.post('/hello', (req, res)=>{
console.log(req.body);
name.push(req.body.name) // add this if you store in array
return res.send(`hello ${req.body.name}`);
})

getting a type Error when running file on node

I'm new to node and express, was trying to test some basics routes but getting a Type Error: Router.use() requires a middle ware function but got an object
This is what I have in app.js
const express = require('express');
const routes = require('./routes/api');
// set up express app
const app = express();
app.use('/api', routes);
//listen for request
app.listen(process.env.port || 4000, function(){
console.log('now listening for requests');
});
and in my api.js:
const express = require('express');
//store router object to a vairable to enable us use routes on api.js
const router = express.Router();
router.get('/ninja', function(req, res){
res.send('{type: "GET"}');
})
router.post('/ninja', function(req, res){
res.send({type: "POST"});
})
//to update an api, where id is a parameter.
router.put('/ninja/:id', function(req, res){
res.send({type: "PUT"});
})
//to delete an api
router.get('/ninja/:id', function(req, res){
res.send({type: "DELETE"});
})
module.exports = router;
I have tried exporting router on each file, none worked.

Router.use() requires a middleware function but got a Object in my node file

New to Node, Please solve the error
Router.use() requires a middleware function but got a Object
const bodyParser = require('body-parser');
const express = require('express');
const app = express();
var productRoutes = require('./api/routes/product');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}))
app.use('/products', productRoutes);
module.exports = app;
api/routes/product.js:
const express = require('express');
const router = express.Router();
router.get('/', (req, res, next) => {
res.status(200).json({message: "Here we are handling the get request for the products"});
});
You change you api/routes/product code . will work fine.
const express = require('express');
const router = express.Router();
router.get('/', (req, res, next) => {
res.status(200).json({
message: "Here we are handling the get request for the products"
});
});
module.exports = router;
The reason was that you was not exporting your router to other file when you write module.exports = router; in file it will export.
app.use('/products', productRoutes);
productRoutes should be a function with this paramters (req, res, next). It could be something like this:
app.use('/products', function(req, res, next) {
// Do the things here
});
if you have any function like this in your productRoutes module, you could export that function and pass it as second parameter in app.use call
If you're refactoring your routes and controllers, it's possible that early in one of your controllers you may list all your routes
router.post('/', GetProducts);
router.post('/add', AddProduct);
followed by
module.exports = router; <-- middleware function
but you may have overlooked an existing module.exports (from before your refactoring) at the end of the controller, which exports all the controller's functions:
module.exports = { fxn1, fxn2, fxn3 }; <-- object
In that case, the later module.exports object would overwrite the earlier module.exports middleware function, and cause this error.

Cannot access to req.body inside middlewares

I actually have a very tiny app in node.js with Express, and I can't access to req.body.
This is my app.js code:
var express = require('express'),
middleware = require('./middleware'),
mysql = require('mysql'),
app = express();
app.use(middleware.authenticate);
app.use(middleware.getScope);
app.listen(3000);
module.exports = app;
And the file with the middlewares:
var bcrypt = require('bcrypt'),
mysql = require('mysql');
function authenticate(req, res, next){
console.log(req.body);
next();
}
function getScope(req, res, next){
console.log(req.body);
next();
}
module.exports.authenticate = authenticate;
module.exports.getScope = getScope;
In all cases req.body is undefined.
I'm sending data throw Postman with x-www-form-urlencoded protocol, in this case is a must.
Thanks!!
You need to add body-parser to express:
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
Check Request here http://expressjs.com/en/api.html
And perhaps a POST route could help too:
app.post('/', function (req, res, next) {
console.log(req.body);
res.json(req.body);
});

Resources