user5854440
user5854440

Reputation: 281

JavaScript/Nodejs : ajax POST request not passing object to backend

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

Answers (1)

Iceman
Iceman

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-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>

Upvotes: 4

Related Questions