Context object is empty while receiving POST request , in Koa? - node.js

I am new in Koa and I am creating a demo app. I want to create an API to handle POST request, But when I console.log(ctx); then there is nothing in ctx in indexRouter.js, the console only printing empty object like {}.
I don't know why this is happening. Please anyone suggest me where I am doing wrong?
And please help me to get the request.body by POST Method.
serverKoa.js:
var koa = require('koa');
var router = require('koa-router');
var app = new koa();
var route = router(); //Instantiate the router
app.use(route.routes()); //Use the routes defined using the router
const index = require('./router/indexRouter')(route);
app.listen(3005 ,function(){
console.log("\n\nKoa server is running on port: 3005");
});
indexRouter.js:
var indexController=require('../controller/indexController');
module.exports = function (route) {
route.post('/postnew',async ( ctx, next) => {
console.log(ctx); // here printing {}
});
}
and my request object ( by postman ) is:
Method: POST,
url:http://localhost:3005/postnew
body:{
"firstName":"viki",
"lastName":"Kumar",
"userName":"vk12kq14",
"password":"098765432"
}
content-type:application/json

It looks like your code has two issues:
you're not using the "next" version of koa-router, which is required if you want to use async/await. You can install it like this:
npm i koa-router#next --save
you're not using koa-bodyparser to parse the request data:
npm i koa-bodyparser --save
To use:
var koa = require('koa');
var router = require('koa-router');
var bodyParser = require('koa-bodyparser');
var app = new koa();
app.use(bodyParser());
...
The parsed body data will be available in your route handlers as ctx.request.body.

Related

Unable to get values in NodeJs Express

I am trying to make post request but unable to get values in Postman; it's sending undefined. I am using Express version 4.17.1. Below is my code:
const express = require('express');
const router = express.Router();
const MongoClient = require('mongodb').MongoClient;
const dburl = process.env.URL;
router.use(express.json());
router.use(express.urlencoded({extended:true}));
router.post('/register',(req,res) => {
var data = {
name:req.body.name,
email:req.body.email,
};
res.send(data);
});
module.exports = router;
What am I doing wrong?
Your code snippet works, tested with express 4.17.1 on node 12.19.0. The issue must be from elsewhere.
Possible issues are:
The parser for router could have been overridden by the parser for app (assuming you're calling app.use(router) somewhere).
Can you move this to app level?
router.use(express.json());
router.use(express.urlencoded({extended:true}));

Cannot extract data from post request in node

I am sending a post request using axios in react to a nodejs backend and mysql database.
At the server side when I log req.body, it is undefined
and this is the params and query part when I log the request on server side:
params: {},
query: {},
This is inside the handlelogin method in react:
handleLogin=(event)=>
{event.preventDefault();
let formfields={...this.state.formfields};
axios.post('http://localhost:7000/api/login',{formfields
})
.then(res=>
{
console.log("response receieved");
})
.catch(err=>
{
console.log(err);
});
};
This is the node script( inside routes):
const express = require('express');
const exp = express();
const bodyParser = require('body-parser');
exp.use(bodyParser.urlencoded({extended:false}));
exp.use(bodyParser.json());
const router = express.Router();
router.post('/api/login',(req,res,next)=>{
console.log('Inside login-serverside');
console.log(req);
});
module.exports = router;
I want to submit forms and pdf files(later) but I cannot access them on the server side.I can acces request.parameters when I make a get request.What is the issue here?
What are body,params and query used for, respectively and what is the difference?
I had not included body parser in my main server.js file
const bodyParser = require('body-parser');
exp.use(bodyParser.urlencoded({extended:false}));
After including this, it's working. I can now successfully use request.body and access the parameters passed in axios.post .
Though I am still confused about the use of params,query,data and body respectively.

Flow of node.js routing when using separate controller and router

In my Node.js project I am using router file that imports controller files that have actual implementation of the methods. Like below.
app.js
'use strict';
var express = require('express');
var app = express();
var apiRoutes = express.Router();
routes.mainApi(apiRoutes);
app.use('', apiRoutes);
apiRoutes
'use strict';
var controller = require('../controller/apiController');
var uploadController = require('../controller/uploadController');
var fileUpload = require('express-fileupload');
module.exports.mainApi = function (apiRouter) {
apiRouter.post('/login', controller.login);
}
apiController
exports.login = function (req, res) {
// My code for login
};
I know when a api request comes then first app.js is executed. It further sends the request to apiRoutes as I called it in file. In apiRoutes when it finds
apiRouts.post(./login,controller.login) then it calls login function from controller. But I want to know that I am not passing req and res parameters anywhere in the login function then how they are being passed. Basically how this type of calling works.
Thanks in advance.
this function controller.login
as a callback parameter of r.post('path', callback)
and when controller.login is actual called by callback(request, response )
you will get req and res

Node express param issue

we are using Node.js + Express as back-end for an Angular2 app. One of the modules of the back-end is responsible for the information gathering about products, based on barcode, which is a param for the Express router. Currently, we're facing an issue when adding a GET request route that does not use the barcode param.
The router file looks as follows:
'use strict';
const express = require('express');
const router = express.Router();
const prodCtrl = require('./controller');
const auth = require('../middlewares/authenticationBearer');
module.exports.init = function(app) {
router.param('barcode', prodCtrl.findById);
router.get('/products/:barcode', auth.bearer(), prodCtrl.getProduct);
router.post('/products/article', auth.bearer(), prodCtrl.getProductData);
router.get('/products/csv', auth.bearer(), prodCtrl.csv);
return router;
}
The problem is the /products/csv route. In its current position, calling the route gives a 404 error seemingly because the param barcode is expected, as the function prodCtrl.findById is called first. By moving this route before the /products/:barcode route like so:
'use strict';
const express = require('express');
const router = express.Router();
const prodCtrl = require('./controller');
const auth = require('../middlewares/authenticationBearer');
module.exports.init = function(app) {
router.param('barcode', prodCtrl.findById);
router.get('/products/csv', auth.bearer(), prodCtrl.csv);
router.get('/products/:barcode', auth.bearer(), prodCtrl.getProduct);
router.post('/products/article', auth.bearer(), prodCtrl.getProductData);
return router;
}
the code works fine. Is this a bug in Express? Or am I missing something here?
You should put '/products/:barcode' route after '/products/article' because it blocks the request to get to the article (the barcode param catch any suffix)

No output from Node app

I am trying to run a simple node application using nide modules and testing it using the Advance Rest Client.
The console is not showing any error.
But I am not getting anything in the output.
While running this on ARC, I am getting : Cannot /GET data
Text version of the code:
MainFile:
var express = require('express');
//var morgan = require('morgan');
var bodyparser = require('body-parser');
var hostname = 'localhost';
var port = '3000';
var app = express();
//app.use(morgan('dev'));
var dishRouter = express.Router();
dishRouter.use(bodyparser.json());
var allDishes = require('./dishRouter');
//For all dishes
dishRouter.route('/dishes')
.get(allDishes.dishesGet)
.delete(allDishes.dishesDelete)
.post(allDishes.dishesPost)
;
//For specific dishesDelete
dishRouter.route('/dishes/:dishid')
.get(allDishes.dishSpecificGet)
.delete(allDishes.dishSpecificDelete)
.put(allDishes.dishSpecificPut)
;
app.listen(port,hostname,function(){
console.log('server runing properly');
});
dishRouter file:
console.log('in dishrouter file');
module.exports.dishesGet = function(req,res,next){
console.log('inside GET');
res.end('Will be displaying all the dishes');
};
module.exports.dishesDelete = function(req,res,next){
res.end('Will delete all the dishes');
};
module.exports.dishesPost = function(req,res,next){
res.end('will add the new dishes');
};
module.exports.dishSpecificGet = function(req,res,next){
res.end('displaying the specific dish :'+req.params.dishid);
};
module.exports.dishSpecificDelete = function(req,res,next){
res.end('Will delete the specific dish with id : '+req.params.dishid);
};
module.exports.dishSpecificPut = function(req,res,next){
res.write('will update the specific dish :'+req.params.dishid);
res.end('Updating the dish with values as name : '+req.body.name);
};
According to body-parser docs
Looks like your router is a bit broken here:
dishRouter.use(bodyParser.json())
Try switching this to:
app.use(bodyParser.json())
And I can recommend creating router in the file, where you write handlers and just export router.
UPDATE:
Here is what you forgot:
app.use(dishRouter)
When calling express.Router() you're just creating an instance of the router, but you have to connect it to the express application instance.

Resources