Im making a angular2/Node.js application. Right now when i try to get a object from the node server, it returns just fine. However, when i try to post data to the node server. The request.body shows undefined. What am i doing wrong ?
server.js
// Test
router.get('/test', function (req, res) {
res.json({test:true}); // Works
});
// Post
router.post('/rest', function (req, res) {
var body = req.body;
console.log(body); // Undefined
res.json({test:true});
});
app.ts
constructor(private http:Http){
console.log("Test")
http.get('/api/User/test').subscribe(result => {
console.log(result.json());
});
let headers = new Headers({ 'Content-Type': 'application/json' });
this.http.post('/api/User/rest',{test:'Testing req'},{headers:headers})
.subscribe(result => {
console.log(result.json());
});
}
Did you install body-parser?
npm install body-parser --save
and before your routes, add it to your express application
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
see also: https://github.com/expressjs/body-parser
Related
I'm new to server-side development.
I'm trying to set up a node.js server that can receive posts.
My client-server code sends the post request:
function post(){
fetch('/clicked', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({a: 1, b: 'Text'})
})
.then(function(response){
if(response.ok){
console.log('POST success.');
return;
}
throw new Error('POST failed.');
})
.catch(function(error){
console.log(error);
});
}
And my Node.js server receives it:
const express = require('express');
const app = express();
app.use(express.json());
app.post('/clicked', (req, res) => {
console.log(req.a);
console.log(req.b);
console.log(req.body);
res.sendStatus(201);
})
However, my server console logs all undefined.
What should I do to receive my POST request body?
Try setting up express.json() inside the app:
const express = require('express');
const app = express();
app.use(express.json())
app.post('/clicked', (req, res) => {
console.log(req.a);
console.log(req.b);
console.log(req.body);
res.sendStatus(201);
});
Add this before handling post request.
app.use(require('body-parser').json());
What body-parser does is, it will add all the information we pass to the API to the 'request.body' object.
I am using express-fileupload to parse the body of my request and access any files that are sent with the request. This works fine when I am trying to do this locally but when I push it to heroku, the files are not being parsed - instead req.files is null. My code is below:
Parsing middleware:
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
const fileUpload = require('express-fileupload');
module.exports = function (app) {
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(fileUpload()); // EXPRESS-FILEUPLOAD BEING USED HERE
};
Routes file:
router.post('/photo', function(req, res, next) {
console.log("INSIDE OF THE ROUTE =======>>>>>");
const userId = req.body.userId;
const busketName = 'my-bucket-name';
let newPhotosArray = [];
var busboy = new Busboy({ headers: req.headers });
req.pipe(busboy);
busboy.on('finish', function() {
const filesObj = req.files;
console.log('FILES OBJ: ', filesObj); // THIS IS LOGGED OUT AS NULL ON HEROKU - LOCALLY IT IS AN OBJECT WITH FILES
// rest of code....
});
});
The code works great when I use it locally. However, when I push the code to Heroku, req.files is null. Why is this?
Sample 'Advanced REST Client' Request
I'm using Postman and Advanced REST client to create a basic POST request for the following code -
'use strict';
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var http = require('http');
// configure the app to use bodyParser()
app.use(bodyParser.urlencoded({
extended: false
}));
app.use(bodyParser.json());
//app.listen(6666);
http.createServer(function (req, res) {
h2s(req, res);
}).listen(6666, '127.0.0.1');
console.log('Server running at http://127.0.0.1:6666/');
module.exports = function h2s(req, res) {
console.log("inside h2s");
app.use(function (req, res) {
console.log("req.body : " + req.body);
res.send("OK");
});
}
But, when I debug, I find that req.body is missing in the "req object tree". What's more strange is all the changes that I make to req.headers are available in the req object tree.
Looks like I seem to be making a trivial mistake, but I'm unable to figure it out. Been trouble-shooting for an hour or so but no luck!
Can anyone of you figure out why req.body seems to be missing from the req object tree?
Will be of great help to me. Thanks!
It looks like you have several issues in your code:
instead of
http.createServer(function (req, res) {
h2s(req, res);
}).listen(6666, '127.0.0.1');
console.log('Server running at http://127.0.0.1:6666/');
module.exports = function h2s(req, res) {
console.log("inside h2s");
app.use(function (req, res) {
console.log("req.body : " + req.body);
res.send("OK");
});
}
For creating the server, try
http.createServer(app).listen(8000, '127.0.0.1'); //using http
Or (using express directly)
app.listen(8000,function(){
console.log('Server running at http://127.0.0.1:8000/');
});
Then register an handler function for your requests, there you can access req.body
app.use(function (req, res) {
console.log("req.body : " + req.body);
res.send("OK");
});
Dear u set body parser Url Encoding to true
// configure the app to use bodyParser()
app.use(bodyParser.urlencoded({
extended: true
}));
and check by printing the req.body, it work for me and might for u also
the req.body can be accessed also when
content-type:"application/x-www-form-urlencoded"
read this
In your case , your content-type is application/json"
so try changing the content-type to "application/x-www-form-urlencoded"
also url encode the parameters while sending to the server from JS
also solution can be
// fire request
request({
url: url,
method: "POST",
json: true,
headers: {
"content-type": "application/json",
},
body: JSON.stringify(requestData)
}, ...
All my requests work perfectly except when I try to add an item to an array of json elements, it will return undefined every time.
Controller:
vm.addOptie = function () {
var newOptie = {"optie": 'stuur',"prijs": 150};
$http({
method: 'post',
url: 'http://localhost:3000/addGekozenOptie',
headers: {
'Content-Type': 'application/json'
},
data: newOptie
}).then(function (gekozenOpties) {
vm.gekozenOpties = gekozenOpties.data;
}).catch(function (err) {
alert('Er is een fout opgetreden: ' + err);
})
}
and my router/index.js
var router = require('express').Router();
var gekozenOpties = require('../public/data/opties.json');
router.post('/addGekozenOptie', function (req, res) {
var op = req.body;
gekozenOpties.push(op);
res.json(gekozenOpties);
});
module.exports = router;
Very frustrating seeing as everything else works fine (get/delete).
Have you tried the following?
//install body-parser
npm install body-parser
//Sample code within your app
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// create application/json parser
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
The bodyParser object exposes various factories to create middlewares.
All middlewares will populate the req.body property with the parsed
body, or an empty object ({}) if there was no body to parse (or an
error was returned).
req.body is always empty. I'm not sure what I'm doing wrong? I tried adding content-type headers as json but that didn't do anything either. Can someone lead me in the correct direction please? Thank you
EDIT: just for clarification purposes, my Angular frontend hits the backend function successfully, but req.body is empty. If I understand everything correctly, if I'm using the 'body-parser' library, it should be passed in through post through 'req.body'. I'm just not seeing that though and I'm not sure why.
EDIT2: I have the body parser code in my app.js but the backend routing in a index.js file, does that have anything to do with it?
EDIT3: app.js http://pastebin.com/9vNgf0Nd
index.js http://pastebin.com/icLa3e2X
ANGULAR FRONTEND
service.registerAccount = function(account) {
console.log(account); //account = { userName: 'test', password: 'hello' }
return $http({
method: 'POST',
url: '/register',
data: { account: account },
headers: {'Content-Type': 'application/json'}
});
}
BACKEND (app.js)
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
BACKEND (index.js)
var express = require('express');
var router = express.Router();
router.post('/register', function(req, res) {
console.log(req.body);
};
Please remove this line
app.use(bodyParser.urlencoded({ extended: true }))
Also,
app.use(bodyParser.json());
have to be called before app.use('/', routes);
And make sure to add Content-Type: application/json to the request header
What happens if you add the content type?
service.registerAccount = function(account) {
console.log(account); //account = { userName: 'test', password: 'hello' }
return $http({
method: 'POST',
url: '/register',
data: { account: account },
headers: {
'Content-Type': 'application/json'
}
});
}
Try this
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/register', function(req, res) {
console.log(req.body);
});
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
});
and then execute this from prompt:
$ curl localhost:8081/register -v --data "{\"name\":\"test\",\"password\":\"hello\"}" --header "Content-Type: application/json"
this works for me!
There is nothing wrong in the UI code. Not sure what is router so you may try this or post the code for router.
Try this (this works for me) or you can also use your router:
app.post('/register', function (req, res) {
console.log(req.body);
res.send('welcome, ' + req.body.account.username)
});
You are missing:
var app = express();
app.use(router);
If you want to user routers refers to following example:
UPDATE with full code:
var express = require('express');
var router = express.Router();
var app = express();
app.use(router);
router.post('/register', function(req, res) {
console.log(req.body);
};
app.route('/register')
.post(function (req, res) {
console.log(req.body);
res.send('welcome, ' + req.body.account.username)
})