Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js: req.params vs req.body

I've been cobbling together code from a few different tutorials to build a basic todo app with the MEAN stack, using node, express, angular, and mongodb. One tutorial covered creating an api for GET, POST, and DELETE actions, but neglected the POST. So, I took it as a challenge to write a function that will update an existing todo. While I got the function working, I encountered an error involving req.params that I didn't understand.

Relevant Code:

Node:

In app.js

app.put('/api/todos/:_id', ngRoutes.update);

which leads to:

exports.update = function(req, res){
    var user_id = req.cookies ?
        req.cookies.user_id : undefined;

    Todo.findByIdAndUpdate(req.params._id, 
        { $set: { 
            updated_at : Date.now(), 
            content : req.body.formText
        }}, function (err, todo) {
    if (err) 
        res.send(err)
    Todo.find({ user_id : user_id}, function(err, todos) {
        if (err) res.send(err);
        res.json(todos);
    });
    });
    };

Angular:

    $scope.update = function(id) {
        $http.put('/api/todos/' + id, this.todo)            
        .success(function(data) {
                    console.log(data);
                    $scope.todos = data;
                })
                .error(function(data) {
                    console.log('Error: ' + data);
                });
  };

Jade/HTML:

form(ng-submit="update(todo._id)")
    input.update-form(ng-show="todo.updating" type="text", name="content", ng-model="todo.formText" placeholder="{{todo.content}}")

This function works fine. It updates the todo in question, and returns the entire list to be reloaded onto the page with the updated value.

However, if in the node code, I change

content : req.body.formText

to

content : req.params.formText

I get the following error as my HTTP response:

Object { 
message: "Cast to string failed for value "undefined" at path "content"", 
name: "CastError", 
type: "string", 
path: "content" }

Even while, elsewhere in the function,

req.params._id

works fine to retrieve the todo's '_id' property and use it to find the appropriate document in the database. Furthermore, when viewing the request in Firefox's developer tools, the todo object appears in JSON format under the "Params" tab.

Why does this happen? What is the difference between using req.params vs req.body, and why does the second work and the first not?

like image 437
Deimyts Avatar asked Jul 26 '14 22:07

Deimyts


People also ask

What is the difference between req params req query & req body?

req. query contains the query params of the request. req. body contains anything in the request body.

What is req body node JS?

The req. body object allows you to access data in a string or JSON object from the client side. You generally use the req. body object to receive data through POST and PUT requests in the Express server.

What is the difference between Request Param and query param in Nodejs?

Both are closely related but they are not the same at all, params are parameters set for the route, query are values resembling variable assignment that provide extra information on what is being required for the route and it will always start with a ? on the URL, inherently they are both string values that express ...

What is difference between params and query params?

They are syntactically the same. Query params are part of your request URL. If you want a dynamic URL like dynamically changing path you can use URI Params.


2 Answers

req.params is for the route parameters, not your form data.

The only param you have in that route is _id:

app.put('/api/todos/:_id', ...)

From the docs:

req.params
This property is an object containing properties mapped to the named route “parameters”. For example, if you have the route /user/:name, then the “name” property is available as req.params.name. This object defaults to {}.

source: http://expressjs.com/en/4x/api.html#req.params

req.body
Contains key-value pairs of data submitted in the request body. By default, it is undefined, and is populated when you use body-parsing middleware such as body-parser and multer.

source: http://expressjs.com/en/4x/api.html#req.body

like image 93
7zark7 Avatar answered Sep 30 '22 13:09

7zark7


req.params is the part you send in the request url parameter or the header part of requests.

req.params example in postman

In example above req.params is the data we are sending in postman after ninjas in the 
url.


    route.delete('/ninjas/:id',function(req,res,next)
{
    Ninja.findByIdAndRemove({_id:req.params.id}).then(function(ninja)
    {
        console.log(ninja.toString());
        res.send(ninja);
    })
    .catch(next);

});

req.body is the part you send in body part of requests

req.body example in postman

req.body is the JSON data we are sending in postman so we can access it in the post request body part.

route.post('/ninjas',function(req,res,next)
{
    Ninja.create(req.body).then(function(ninja)
    {
        console.log("POST"+req.body);
    res.send(ninja);
    })
    .catch(next);

});
like image 43
Pragyanshu Sharma Avatar answered Sep 30 '22 12:09

Pragyanshu Sharma