1

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.

6
  • are you using express.js? if so is bodyParer setup properly? Commented Jul 7, 2016 at 22:29
  • Cud you post more of your node.js code then? Commented Jul 8, 2016 at 4:24
  • to follow on @Iceman's comment, ensure you've set up body-parser to use JSON and not urlencoded. Commented Jul 8, 2016 at 4:50
  • @zim he said he has set it up. "I am using bodyParser.json()". So, I think we need the full code to see what is actually happening. Commented Jul 8, 2016 at 4:54
  • @Iceman I've made the edits to show my back end code and all the code I am using in express. Commented Jul 10, 2016 at 1:59

1 Answer 1

4

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-parsermiddleware 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>
Sign up to request clarification or add additional context in comments.

4 Comments

Body parser is not the problem, as I had it set up as stated.
@user5854440 ok. missd that!!
@user5854440 I have undeleted the answer, this is the solution. the problem was the body parser not identifying the content type, so added the header, plus I also stringified the data before sending.
Thank you so much. I added both the JSON.stringify function and the xhr.setRequestHeader with the proper MIME type, and it works now. Another shout out to how readable your changes were.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.