n4feng n4feng - 1 month ago 7
JSON Question

can't find my json file in req.body when sending it through http post request

I have almost finished adding a new feature on my application trying to pass a json file from angular frontend to node backend via express. The original code come from How do I write a JSON object to file via Node server?. My controller part code look like:

var app = angular.module('myApp',[]);
app.controller('myCtrl',function ($scope, $http){
$scope.saveImage = function(){
var data = JSON.stringify(canvas);
debugger;
$http({
url: 'http://localhost:8080',
method: "POST",
data: data,
header: 'Content-Type: application/json'
});
}
});


I can see from developer tool that the json string "data" do have been created and has lots of things in it in my controller front end. But while I am passing it to node side, I can't get anything from req.body.
Here is my backend code:

// set up
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({extended: false}));
var saveCount = 1;
//functions
// application -------------------------------------------------------------
app.use(express.static('./public'));

app.get('/', function (req, res) {
res.send('Hello World!');
});

app.post('/', function (req, res) {
fs.writeFile(__dirname+"/save/post"+saveCount.toString()+".json", req.body, function(err) {
if(err) {
return console.log(err);
}
res.send('The file was saved!');
});
saveCount++;
});

//listen
app.listen(8080, function () {
console.log('Example app listening on port 8080!');
});


Every time when I check my psot.json files, it only have [object Object]

I have exactly no idea what is happening here.

Answer

A few things:

  1. You don't need to call JSON.stringify() on your data object. Just pass the object to $http as is.
  2. You need to pass bodyParser.json() not bodyParser.urlencoded().
  3. JSON.stringify() should be called before you try to write to your file.

Your code should look like:

var app = angular.module('myApp',[]);
app.controller('myCtrl',function ($scope, $http){
  $scope.saveImage = function(){
    debugger;  // What does this do?
    $http({
      url: 'http://localhost:8080',
      method: "POST",
      data: canvas,
      header: 'Content-Type: application/json'
    });
  }
});

And

// set up
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require("body-parser");
app.use(bodyParser.json());
var saveCount = 1;
//functions
// application -------------------------------------------------------------
app.use(express.static('./public'));

app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.post('/', function (req, res) {
  fs.writeFile(__dirname+"/save/post"+saveCount.toString()+".json", JSON.stringify(req.body), function(err) {
    if(err) {
       return console.log(err);
    }
    res.send('The file was saved!');
  }); 
  saveCount++;
});

//listen
app.listen(8080, function () {
  console.log('Example app listening on port 8080!');
});

That [object Object] means that your object is actually making it to the server and being parsed properly, that's just the representation of that object. You really don't need to stringify on the front end, however. $http will handle sending the object for you, you are just creating extra work for your application. And while bodyParser may be picking up the post data (possibly because of how you've handled it on the front end), what you really want is for bodyParser to parse it as a JSON object with the .json() method, because that's what it is.

If you don't want to go through all of that, you could keep things as you have it now and change your Content-Type to application/text or similar so that it's not parsed as an object when it gets to the server.