mattr
mattr

Reputation: 87

Data is not passed from AngularJS controller to NodeJS server

I am attempting to pass some values from my client-side AngularJS script to a server-side NodeJS script. I set up the POST request like so:

    $scope.addUser = function() {
        console.log($.param($scope.user));
        $http({
            method: 'POST',
            url: '/addUser',
            data: $.param($scope.user),
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
        }).
        success( function(response) {
            console.log("success");
        }).
        error( function(response) {
            console.log("error");
        });

    };

The $scope.user variable is { name: "john", email: "doe" }, and evaluates to name=john&email=doe when passed through $.param($scope.user). I originally thought the problem was the content-type of the request, which was originally a JSON object. After reading about similar problems I changed the content-type to x-www-form-urlencoded, but still could not grab the data from the POST request.

Here is the server-side NodeJS script that is hit with the POST request:

app.post('/addUser', function(req, res) {
    console.log(req.params);
});

I know the server-side script is being reached, as I can print out data such as req.method, but attempting to print req.params results in just { }.

Why are my POST parameters not going through?

Upvotes: 1

Views: 3570

Answers (2)

Dalorzo
Dalorzo

Reputation: 20014

Since you are using express.js your POST fields are received as part of the body not the URL so you need use body instead of params:

app.post('/addUser', function(req, res) {
    console.log(req.body);//also possible req.body.name | req.body.email
});

How about trying a simpler POST something like this (for testing purposes only):

  $http.post('/addUser',{ "name": "john", "email": "doe" }).success(function(response) {
           console.log("success");
          }).error(function(err){
             console.log("failure")
          });

Please note that Params are used as URL parameters; something like this:

app.get('/addUser/:userID', function(req, res) {
        console.log(req.params.userID);
});

Upvotes: 0

mscdex
mscdex

Reputation: 106696

Request bodies are not saved to req.params. You need to add a middleware to parse the request body for you. req.params is for key=value pairs supplied as part of the URL (e.g. POSTing to "/foo/bar?baz=bla" would result in req.params.baz === 'bla').

Some example solutions:

  • body-parser - parses only application/json and application/x-www-form-urlencoded request bodies.

  • formidable - parses application/json, application/x-www-form-urlencoded, and multipart/form-data. This is what was used in the body parser in Express 3. I'm not sure if there is an "official" Express middleware for it for Express 4.

  • busboy - parses application/x-www-form-urlencoded and multipart/form-data. It does not save files to disk itself, but instead presents files as readable streams. The API differs from formidable(/body parser from Express 3). There are a few Express middleware available for busboy:

    • connect-busboy - a thin wrapper that merely sets up a Busboy instance on your req. You can set it to automatically start parsing the request, or you can pipe the request manually to req.busboy when you want to start.

    • multer - provides an interface more similar to the Express 3 body parser middleware (with req.body and req.files set).

    • reformed - a new module that provides a layer on top of Busboy to provide mechanisms similar to formidable (e.g. saving uploaded files to disk) but also other features such as field validation.

Upvotes: 1

Related Questions