Reputation: 281
I'm attempting to post a JSON object to my server, but when I console log req.body
it shows an empty object. Here's my code:
var submitRecipe = () => {
let recipe = {alias: null, description: null, instructions: null};
recipe.alias = document.getElementById('alias').value;
recipe.description = document.getElementById('description').value;
recipe.instruction = document.getElementById('instructions').value;
postRequest("/createrecipe", recipe, (xhr) => {
console.log("Hello!" + JSON.parse(xhr.responseText));
})
};
var postRequest = (url, data, callback = undefined) => {
xhr.onreadystatechange = () => {
//Call a function when the state changes.
if(xhr.readyState == 4 && xhr.status == 200) {
console.log("testing");
return callback(200 , xhr.responseText);
}else{
return callback(400, xhr.responseText);
}
}
xhr.open('POST', url)
xhr.send(data);
}
Node
createRecipe = function(req, res){
console.log(req.body);
}
I'm using express to transfer the server information, and I am using bodyParser.json()
. From there, I just call the controller with the following:
express
var express = require("express");
var bodyParser = require("body-parser");
var server = express();
var recipeController = require("./controllers/recipeController");
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true}));
server.post("/createrecipe", recipeController.createRecipe);
The createRecipe
function just console logs the information, but as stated before, req.body
is an empty object. All tips are appreciated.
Upvotes: 1
Views: 817
Reputation: 6145
XHR expects your data to be encoded or packed in whatever way you expect it to be send unlike other library wrappers like jQuery or Angular Ajax wrapper functions.
Alsobody-parser
middleware was not identifying the Content-type and was not activating for the required request.
Simply JSON.stringify
your json data
data = JSON.stringify(data);
and add the application/json
MIME type as xhr
's content-type
header.
xhr.setRequestHeader("content-type", "application/json");
Also, If you want to use url-encoded
do the encoding of your data before attaching and add the corresponding header content type.
My full test code (for reference purposes):
Server (testServer.js
):
var express = require("express");
var bodyParser = require("body-parser");
var server = express();
server.use(bodyParser.json());
server.use(bodyParser.urlencoded({ extended: true}));
server.post("/createrecipe", function(req, res){
console.log(req.body);
var resp = {server: "hello world", dataReceived: req.body};
res.json(resp);
});
server.get("/", function(req, res){
res.sendFile(__dirname + "/testClient.html");
})
server.listen(3000, function(){
console.log("Server running");
})
Client (testClient.html
):
<input type="text" id="alias" value="a">
<input type="text" id="description" value="b">
<input type="text" id="instructions" value="c">
<button onclick="submitRecipe()"> TEST</button>
<script>
var submitRecipe = () => {
let recipe = {alias: null, description: null, instructions: null};
recipe.alias = document.getElementById('alias').value;
recipe.description = document.getElementById('description').value;
recipe.instructions = document.getElementById('instructions').value;
postRequest("/createrecipe", recipe, (status, xhr) => {
var data = (JSON.parse(xhr.responseText));
console.log(data.dataReceived);
})
};
var postRequest = (url, dataObj, callback = undefined) => {
//--------------Added line--------------------
var data = JSON.stringify(dataObj);
//--------------Added line--------------------
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
//Call a function when the state changes.
if(xhr.readyState == 4 && xhr.status == 200) {
return callback(200 , xhr);
}else if(xhr.status == 400){
return callback(400, xhr);
}
}
xhr.open('POST', url)
//--------------Added line--------------------
xhr.setRequestHeader("content-type", "application/json");
//--------------Added line--------------------
xhr.send(data);
}
</script>
Upvotes: 4