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?
req. query contains the query params of the request. req. body contains anything in the request body.
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.
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 ...
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.
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
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);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With