15

I am trying to post data from my react. Backend - express. Here is backend code:

var express = require('express');
var app = express();
var bodyParser = require("body-parser");
var  methodOverride = require("method-override");
var mongoose = require("mongoose");
var expressSanitizer = require("express-sanitizer");

mongoose.connect("mongodb://localhost/blog-react");

//app config
app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(bodyParser.urlencoded({extended: true}));
//must be after parser
app.use(expressSanitizer());
app.use(methodOverride("_method"));

//schema config
var blogSchema = new mongoose.Schema({
    title: String,
    image: String,
    body: String,
    //it should be date. With default value now.
    created: {
        type: Date, default: Date.now
    }
});

var Blog = mongoose.model("Blog", blogSchema);


function handle500(response, error){
    console.log(error.stack);
    response.status(500);
    response.json({error: "error: internal server error"});     
}

app.post("/api/blogs", function(request, response){         
    var blog = {
        title: request.sanitize(request.body.title),
        image: request.sanitize(request.body.image),
        body: request.sanitize(request.body.body)
    };
    console.log(request.body);
    Blog.create(blog, function(error, newBlog){
        if(error){
            console.log("inside post handler ERROR")
            handle500(response, error);
        }
        else{
            console.log("inside post handler OK")
            response.json({status: "success"});         
        }
    }); 
});

React code:

    var requestUrl = "/api/blogs";      
    var blog = {
        title: "a",
        image: "b",
        body: "c"
    }   
    axios.post(requestUrl, blog)
    .then(function(response){
        console.log("success",response.data)
    })
    .catch(function(response){
        console.log("error", response);
    }); 

When I post data via axios - request.body is always {} But if I post data via regular form - all is correct - request.body contains all expected data.

What am I doing wrong with axios?

kurumkan
  • 2,635
  • 3
  • 31
  • 55

4 Answers4

33

You are missing one middleware, bodyParser.json(). Add it to your configuration.

mongoose.connect("mongodb://localhost/blog-react");

app.set("view engine", "ejs");
app.use(express.static("public"));
app.use(bodyParser.json()); // <--- Here
app.use(bodyParser.urlencoded({extended: true}));
QoP
  • 27,388
  • 16
  • 74
  • 74
  • I logged in just to thank you. I was using `bodyParser.urlencoded` without knowing it's entirely different from the `bodyParser.json()` option. – Bersan Dec 06 '19 at 01:14
5

For people using Express>=4.16, bodyParser has been changed to the following:

app.use(express.json());
darkvalance
  • 390
  • 4
  • 14
3

For me the issue was valid JSON format including double quotes on the variables.

This did not work

      const res = await axios.post(serverPath + "/user/login", {
         email: email,
         password: password,
      });

This DID work (with double quotes around email and password)

      const res = await axios.post(serverPath + "/user/login", {
         "email": email,
         "password": password,
      });
Michael Nelles
  • 5,426
  • 8
  • 41
  • 57
  • 1
    Both are the same – Coal Jun 20 '21 at 07:12
  • The 2nd one has double quotes on the variable name left of the `:` – Michael Nelles Jun 21 '21 at 12:16
  • Both are the same in the aspect that using quotes when declaring the object key does not change anything regarding to the object. The quotes do not make a difference unless you want to use a key that’s not a valid JavaScript identifier. – Coal Jun 22 '21 at 16:17
  • JSON objects differ from Javascript objects in that the variable name `must` be enclosed with double quotes https://json-schema.org/understanding-json-schema/reference/object.html – Michael Nelles Jun 23 '21 at 12:06
  • JSONs are not objects, they are serialized strings. When you parse a JSON string, you actually deserialize it, which converts it into an actual object in memory. – Coal Jun 23 '21 at 17:11
  • When using braces in JavaScript you are defining an object. I think you'd be interested in this article: https://mathiasbynens.be/notes/javascript-properties – Coal Jun 23 '21 at 17:14
  • 1
    I agree thank you. This was never my intended point. I made the post in the hopes of saving someone time who may have needed to change the format of their object in the event that this as the erroneous factor. In my particular case the object being received had to be done in this format. – Michael Nelles Jun 24 '21 at 11:55
1

It looks like you only have two points left to make it work :

one : the http method should be set to POST instead of GET since you want to send something.

two : you can then add the http header (like what you did with the authorization header) Content-Type: 'application/json`

On the back-end don't forget to use some kind of body parser utility package like this one : body-parser and set it up with your app.

I suppose your server is using express, here is how you will do it with express :

const express = require('express');
const app = express();
const bodyParser = require('body-parser')
const jsonParser = bodyParser.json();

app.use(jsonParser); // use it globally
app.get('your_route', jsonParser, otherMiddleware, (req, res) => ...); // use it for specific routes

/* ... rest of your code */
ali Atwa
  • 415
  • 5
  • 13