server.js
uses the body parser middleware, handlebars and express
route
module.exports = function (app) {
app.post('/questionnaire/submit', function (req, res) { // Ajax Call
var data = JSON.parse(req.body);
res.send({});
});
};
client
function submitData() { // Send a data object to the server
$.ajax({
type: 'POST',
url: '/questionnaire/submit',
dataType: "json",
data: JSON.stringify({
satisfactory: "text 1",
improvement: "text 2",
rating: 0.7
})
}).done(function () {
$(location).attr('href', '/sendOff');
}).fail(function () {
});
}
when logging req.body
I get a JSON string
{ '{"satisfactory":"text 1","improvement":"text 2","rating":0.7}': '' }
and I try to parse this string to an object. When I do so, I get this error message
TypeError: Cannot convert object to primitive value at JSON.parse (<anonymous>) at C:\Users\mah\Desktop\FeedbackTool\Server\Routes\questionnaire.js:12:25 at Layer.handle [as handle_request] (C:\Users\mah\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users\mah\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (C:\Users\mah\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users\mah\node_modules\express\lib\router\layer.js:95:5) at C:\Users\mah\node_modules\express\lib\router\index.js:281:22 at Function.process_params (C:\Users\mah\node_modules\express\lib\router\index.js:335:12) at next (C:\Users\mah\node_modules\express\lib\router\index.js:275:10) at C:\Users\mah\node_modules\body-parser\lib\read.js:130:5
so how can I parse the string to an object?
Normally I would execute JSON.parse(req.body)
.
server.js
uses the body parser middleware, handlebars and express
route
module.exports = function (app) {
app.post('/questionnaire/submit', function (req, res) { // Ajax Call
var data = JSON.parse(req.body);
res.send({});
});
};
client
function submitData() { // Send a data object to the server
$.ajax({
type: 'POST',
url: '/questionnaire/submit',
dataType: "json",
data: JSON.stringify({
satisfactory: "text 1",
improvement: "text 2",
rating: 0.7
})
}).done(function () {
$(location).attr('href', '/sendOff');
}).fail(function () {
});
}
when logging req.body
I get a JSON string
{ '{"satisfactory":"text 1","improvement":"text 2","rating":0.7}': '' }
and I try to parse this string to an object. When I do so, I get this error message
TypeError: Cannot convert object to primitive value at JSON.parse (<anonymous>) at C:\Users\mah\Desktop\FeedbackTool\Server\Routes\questionnaire.js:12:25 at Layer.handle [as handle_request] (C:\Users\mah\node_modules\express\lib\router\layer.js:95:5) at next (C:\Users\mah\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (C:\Users\mah\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (C:\Users\mah\node_modules\express\lib\router\layer.js:95:5) at C:\Users\mah\node_modules\express\lib\router\index.js:281:22 at Function.process_params (C:\Users\mah\node_modules\express\lib\router\index.js:335:12) at next (C:\Users\mah\node_modules\express\lib\router\index.js:275:10) at C:\Users\mah\node_modules\body-parser\lib\read.js:130:5
so how can I parse the string to an object?
Normally I would execute JSON.parse(req.body)
.
-
"when logging req.body I get a JSON string" That doesn't look like a JSON string to me. It looks like something with JSON in it, but the
{ '
at the beginning isn't JSON (and the end looks odd). – T.J. Crowder Commented Dec 5, 2017 at 14:17 -
@T.J.Crowder It's a string in the form
{ '<json>': '' }
, ie an entire JSON document as the key of another JSON document, except you can't choose to use'
in JSON, so the outer document isn't valid. – user229044 ♦ Commented Dec 5, 2017 at 14:19 -
@meagar: Property names and other strings are always in double quotes in JSON. (Edit: Ah, you edited. :-) ) And since the OP is using
JSON.stringify
, we know it won't have single-quoted strings... – T.J. Crowder Commented Dec 5, 2017 at 14:20
3 Answers
Reset to default 5You need to setup correct contentType:
$.ajax({
type: 'POST',
url: '/questionnaire/submit',
contentType: 'application/json',
data: JSON.stringify({ satisfactory: "text 1", rating: 0.7 })
});
app.post('/questionnaire/submit', function (req, res) { // Ajax Call
var data = JSON.parse(req.body);
console.log(data.rating); // 0.7
res.send(data);
});
Also, with body-parser
you may avoid JSON.parse
calls on the server side, the link.
Since you are using body-parser
middleware then you dont have to parse req.body
again cause it already parsed by body-parser
Example
if you used
app.use(bodyParser.json())
then you just have to do this
module.exports = function (app) {
app.post('/questionnaire/submit', function (req, res) { // Ajax Call
var data = req.body; // this is already parsed and is an object
res.send({});
});
};
as pointed out by @T.J. Crowder you should also send the correct contentType
so body-parser
knows its json
function submitData() { // Send a data object to the server
$.ajax({
type: 'POST',
url: '/questionnaire/submit',
contentType: 'application/json',
data: JSON.stringify({
satisfactory: "text 1",
improvement: "text 2",
rating: 0.7
})
}).done(function () {
$(location).attr('href', '/sendOff');
}).fail(function () {
});
}
dataType
doesn't say what type of data you're sending, it says what type of response you expect. You need to say that you're sending JSON, via contentType: "application/json"
in your ajax
call. Details in the documentation. (You're not the first or only person, by far, to be tripped up by the naming of dataType
.)
That's half the problem. See Stamos' answer for the other half.