I use MongoDB as the back-end database for my node/Express application. To summarize the problem I am facing, I don't know how to set up the body-parser configuration in my Express app, because the server side application is not receiving the full JSON posted by the client application (also a node.js app). For the most part, the client is sending JSON in the request body to RESTful endpoints. The exception being a single case where a file needs to be uploaded and since that is a multipart body, I am using request and form-data to build that type of request and using multer on the server side to process the multipart request, since body-parser does not process such requests.
On the server-side (Express), I have the following configuration of the Express app:
let app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
On the node client, I am using the following code to build up a JSON-style JavaScript object and post it to a RESTful endpoint:
I am having difficulty composing the request on the client side, with node-request:
// class is a JavaScript/JSON object within scope of this code
let req = request.post({
//headers: { 'Content-Type': 'application/json' },
url: 'http://localhost:3000/classes',
//form: class
form: JSON.stringify(class)
}, function (err, resp, body) {
if (err) {
throw err;
}
});
Note that I attempted multiple versions of the above code by explicitly specifying the content type as application/JSON
, as well as using JSON.stringify
to convert the JavaScript object into a JSON string. The MongoDB collection (class
) stores the following type of document, which contains foreign keys to two other collections (subject
and student
):
{
"_id" : ObjectId("57758f15f68da08c254ebee1"),
"name" : "Grade 5 - Section A",
"scores" : [{
"studentId" : ObjectId("5776bd36ffc8227405d364d2"),
"performance": [{
"subjectId" : ObjectId("577694ecbf6f3a781759c54a"),
"score" : 86,
"maximum" : 100,
"grade" : "B+"
}]
}]
}
In the server logs, I see the following error:
Tue, 05 Jul 2016 04:34:46 GMT classReportApp:routes:classes class received from client: { _id: 577b38e65967097c25876764, scores: [] }
RangeError: Invalid status code: 0
at ServerResponse.writeHead (_http_server.js:192:11)
at ServerResponse.writeHead (C:\Development\classReportApp\node_modules\morgan\node_modules\on-headers\index.js:55:19)
at ServerResponse._implicitHeader (_http_server.js:157:8)
at ServerResponse.OutgoingMessage.end (_http_outgoing.js:566:10)
at ServerResponse.send (C:\Development\classReportApp\node_modules\express\lib\response.js:205:10)
at ServerResponse.json (C:\Development\classReportApp\node_modules\express\lib\response.js:250:15)
at C:\Development\classReportApp\server-process\app.js:80:26
at Layer.handle_error (C:\Development\classReportApp\node_modules\express\lib\router\layer.js:71:5)
at trim_prefix (C:\Development\classReportApp\node_modules\express\lib\router\index.js:310:13)
at C:\Development\classReportApp\node_modules\express\lib\router\index.js:280:7
at Function.process_params (C:\Development\classReportApp\node_modules\express\lib\router\index.js:330:12)
which is strange because scores array of sub-documents is empty (scores: []
), whereas on the client side, I am sending a non-empty array with some students' performances elements in it.
Have I violated the right way to post JSON to Express apps? How do I fix this?
Edited: 7/5/2016
I changed the body parser middle-ware configuration to use extended: true
instead.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
The node.js is still using the node-request module to compose and send the POST request, using the following code:
let req = request({
url: 'http://localhost:3000/classes',
method: 'POST',
json: class
}, function (err, resp, body) {
if (err) {
throw err;
}
else {
// process response
}
});
This works now, but what confuses me is that since the content type is application/json, how does the bodyParser.urlencoded({ extended: true })
(or false) matter?