How to get the request payload from a PATCH request in express - node.js

I'm using Ember.js alongside an Express webserver. The default JSONApi adapter calls update records with a PATCH request to the server setting the Request Payload in the request to the server.
I'm having a hard time getting that data out of the request on my express server
Here is an example request Ember is sending to the server
The relevant code for the express server looks like this
app.route('/tags/:id')
...
.patch(tag.updateTag);
// UpdateTag
function updateTag(req,res) {
Tag.findById({_id: req.params.id}, (err,tag) => {
if(err) res.send(err);
Object.assign(tag, req.body).save((err,tag) => {
if(err) res.send(err);
res.json(TagSerializer.serialize(tag));
});
});
}

I was able to get this working. In express I'm also using the jsonapi-serializer npm module to do serialization and deserialization
Turns out I need to do my deserialization and in it's callback use the data to update with rolls eyes
function updateTag(req,res) {
TagDeserializer.deserialize(req.body,(err,deserializedTag)=>{
if(err){
res.send(err);
} else {
Tag.findById({_id: req.params.id}, (err,returnedTag) => {
if(err) res.send(err);
Object.assign(returnedTag, deserializedTag).save((err,updatedTag) => {
if(err) res.send(err);
res.json(TagSerializer.serialize(updatedTag));
});
});
}
})
}

Related

NodeJs not running in the port 4000

I am trying to call an api using axios in react.I am using express and node js .when api is called using axios.get() .it returns error after some time.when i run node in port 4000(localhost:4000/data) its not loading.
//api
router.route('/issue').get((req, result) => {
Issue.find((err, issue) => {
if (err)
console.log(err);
else
result.json(issue);
});
});
//api call in react file
axios.get('http://localhost:4000/issue').then(res=>{
console.log('success');
}).catch(err=>{
console.log('error');
});
You need to handle the error in your api. If you just console.log, your frontend is still waiting for a response
And if your back don't sent any response, your browser cancel the request with a timeout, that is the error you got
//api
router.route('/issue').get((req, result) => {
Issue.find((err, issue) => {
if (err)
result.status(404).json({
success: false,
msg: "There has been a problem in your request"
});
else
result.json(issue);
});
});

Try catch in server side affect error handling in react

I'm working on a web app that works with node in server and react-redux in front-end.
The App is handling errors by redux in front-end and I want to use try-catch for the server because I want to keep my server working(sometimes because of one simple error server will be down).
But as try-catch is catching the error in the server after using try-catch in node (server) I'll not receive any message for that error in front-end( I have received a message related to error as I'm using redux)
My question is that: How can I handle my app to have error handling on both side? If I don't use try catch in the server, the server will be down. I want to have error-handling alongside in server and front-end.
For example, this is Update route in my app that I want to use try-catch, I have added this try-catch and now I can have the error in server console and in front-end by using a callback. But is it the correct way?
app.put('/updateadmin', function(req, res, cb){
var email = req.body.email,
// password = req.body.password,
name = req.body.name;
admin.updateAdmin(email, name, function(err, user){
if (err)
throw err;
try {
activity.insertActivity(user._id, 4, function(err){
if (err)
throw err;
});
} catch (ex) {
cb(ex);
console.log(ex);
}
});
});
Thanks for help
I found this way to handle errors in express site:
app.put('/updateadmin', function(req, res, next){
var email = req.body.email,
name = req.body.name;
admin.updateAdmin(email, name, function(err, user){
if (err)
return next(err);
activity.insertActivity(user._id, 4, function(err){
if (err)
return next(err);
});
});
});
and in the top level of your app like App.js, you should handle errors.

Node Request inside request with cookie

I am using node request var request = require(“request”); in my config node to do a POST request and in response get a Cookie which need to be referred in all rest of requests.
I tried enabling COOKIE JAR that works fine if i chain my request under first request but I want to call rest of requests like GetList from custom node.
I tried toughcookie (file cookie) not working when i add var j = request.jar(new FileCookieStore(‘cookies.json’));
node stop working with no error.
Below is my config node, code using which I am getting Cookie.
function myAuthNode(n) {
RED.nodes.createNode(this,n);
this.username=n.username;
this.password=n.password;
this.connect=function(){
//TODO-NG need to make URL configurable
request.post({url: "http://localhost:8080/api/method/login", qs: {usr: this.username, pwd: this.password}}, function(err, res, body) {
if(err) {
return console.error(err);
}
console.log("HERE IF I PUT REQUEST Works fine");
console.log("CAN WE PASS ANOTHER REQUEST here from calling SOURCE to execute here?");
});
};
}
Here in this custom node I am calling
// The main node definition - most things happen in here
function GetListNode(n) {
// Create a RED node
RED.nodes.createNode(this,n);
console.log('I am called');
//using auth config now you are connected, tell me what is needed?
this.authConfig=RED.nodes.getNode(n.auth);
//connect to config and do auth
this.authConfig.connect();
//THIS ALWAYS FAILS due to cookie not found where as I enable request JAR
request.get({url: "http://localhost:8080/api/resource/Project"}, function(err, res, body) {
if(err) {
return console.error(err);
}
console.log("Response body:", body);
});
}
Please suggest how to handle cookie in request so that all requests after auth works fine?
Can we pass a request definition to another request for execution inside it or how Cookie can be handled ?
I resolved this by doing below inside GetListNode(), i shifted second request inside the call:
this.authConfig.connect(function(){request.get({url: "http://localhost:8080/api/resource/Project"}, function(err, res, body) {
if(err) {
return console.error(err);
}
console.log("Response body:", body);
});});
and inside config node i did below, added a function parameter and called that passed function, WORKED fine :):
this.connect=function(f){
//TODO-NG need to make URL configurable
request.post({url: "http://localhost:8080/api/method/login", qs: {usr: this.username, pwd: this.password}}, function(err, res, body) {
if(err) {
return console.error(err);
}
f.call();
});
};

Express Not able to get request body value

I am trying to learn the MEAN stack by following a tutorial for CRUD operations using REST Api with express and mongoose. I am able to run the GET and DELETE operations but I am not getting the POST and PUT operations because I am not getting the required request body values.
router.post('/', function (req, res, next) {
var todoObject = {
name: req.body.name
};
Todo.create(todoObject, function (err, todo) {
if (err) res.send(err);
Todo.find(function (err, todos) {
if (err) res.send(err);
res.json(todos);
});
}); });
As you can see from the code that I am setting the name parameter of the json object using the request body value which I pass through POSTMAN. A new document is getting created but the name value is unset in the database.
However, giving the name directly works. Please help me.
the simplest and safest way is to send JSON object from the client using RAW data.
so ,to implement it follow the steps below:
Set the Content/type to application/json in the Headers
Select raw type and put your JSON object in the Body
And finally Your code should be like:
router.post('/', function (req, res, next) {
var todoObject = req.body;
Todo.create(todoObject, function (err, todo) {
if (err) res.send(err);
Todo.find(function (err, todos) {
if (err) res.send(err);
res.json(todos);
});
});
});
You need to use Content-Type: application/json in Headers if it is with JSON format.

Save to database on change, angular and node js

I'm converting an MS Access database to a webapp. I'm using Angular JS, Node JS with the express framework and MySQL as database.
In ms access you don't have any edit/save features. When you edit something, the database changes instantly. I like this. Feels smooth. So I want to have this the same way in the web app. My question is. Will there be any problems with this approach in my webbapp?
This is a piece of my node js code which updates the database with a restcall:
/*
Post /api/products/ HTTP/1.1
*/
exports.editProduct = function(req, res) {
console.log(req.body);
var post = [{title_en: req.body.title_en},req.params.id];
if (connection) {
connection.query("UPDATE products SET ? WHERE id = ?", post, function(err, rows, fields) {
if (err) throw err;
res.contentType('application/json');
res.write(JSON.stringify(rows));
res.end();
});
}
};
And on the client side I use the a the $resource object
$scope.save = function(){
$scope.product.$save(function(){
console.log('Save successfull);
});
};
And in the view. I simply have inputs with ng-change:
<input ng-model="product.title_en" ng-change="save()".
Will this work good in production mode with a couple hundred users? Is the chances of blocking/crashing etc?
The only thing I see is if (err) throw err;
if there is an error the server crash so change it with a json response with a 500 status.
By the way express has a build-in way to output json
It's better off to validate title_en and id
exports.editProduct = function(req, res) {
console.log(req.body);
var post = [{title_en: req.body.title_en},req.params.id];
if (connection) {
connection.query("UPDATE products SET ? WHERE id = ?", post, function(err, rows, fields) {
if (err) {
return res.json(500,{ error: 'Cannot update the product' });
}
res.json(200,rows);
});
}
an other thing try to use restangular instead of resource it's a lot of fun :)
};

Resources