how can I call PUT after GET in Express - node.js

Requesting GET then PUT in Postman works as expected, although I don't see how to programmatically do this in node.
example:
Request GET localhost:3000/orders/Asia
returns 50 stock
Request PUT localhost:3000/orders/Asia/40
returns 10
app.get('/orders/:coffeeid', function(req, res) {
db.collection('coffees').find({'name': req.params.coffeeid}).toArray((err, result) => {
if (err) return res.send(500, err)
var data = {
"orders": {
"name": result.coffeeid,
"stock": result.stock
}
};
res.json(result);
})
})
app.put('/orders/:coffeeid/:quantity', function(req, res) {
db.collection('coffees').find({'name': req.params.coffeeid}).toArray((err, result) => {
if (err) return res.send(500, err)
orders = {
"name": req.params.name,
"quantity": req.params.quantity
};
console.log(result[0].stock, orders.quantity, orders.quantity <= result[0].stock) // resolvido
console.log(orders.quantity)
if (Number(orders.quantity) <= Number(result[0].stock) ) {
result[0].stock = result[0].stock - orders.quantity
db.collection('coffees').updateOne({'name': req.params.coffeeid}, result[0], function(err, result) {
console.log('Order dispached. Thank you');
res.json(result);
res.render('orders.ejs', {orders: result, success: false})
});
}
else {
console.log('There isnt enough in stock. Will dispach ASAP');
res.json({error: true});
}
})
})
How can I programmatically call update after "getting" the stock value from get?
Thanks

If I understand correctly, the answer will be is instead of declaring anonymous function for PUT request, you can do this
`
const whatEverYouWant =function(req, res) {
db.collection('coffees').find({'name': req.params.coffeeid}).toArray((err, result) => {
if (err) return res.send(500, err)
orders = {
"name": req.params.name,
"quantity": req.params.quantity
};
console.log(result[0].stock, orders.quantity, orders.quantity <= result[0].stock) // resolvido
console.log(orders.quantity)
if (Number(orders.quantity) <= Number(result[0].stock) ) {
result[0].stock = result[0].stock - orders.quantity
db.collection('coffees').updateOne({'name': req.params.coffeeid}, result[0], function(err, result) {
console.log('Order dispached. Thank you');
res.json(result);
res.render('orders.ejs', {orders: result, success: false})
});
}
else {
console.log('There isnt enough in stock. Will dispach ASAP');
res.json({error: true});
}
})
}
app.get('/orders/:coffeeid', function(req, res) {
db.collection('coffees').find({'name': req.params.coffeeid}).toArray((err, result) => {
if (err) return res.send(500, err)
var data = {
"orders": {
"name": result.coffeeid,
"stock": result.stock
}
};
yourPutRequest(req,res) //
res.json(result);
})
})
app.put('/orders/:coffeeid/:quantity',whatEverYouWant)
`

Related

Update database

I am struggling to get .put or .patch to work. when using postman I get the call back returned but the values are not updated in my database on robo 3t. I have tried fixing the deprecation warning and using updateOne, updateMany.
This will fix the deprecation warning but will not update the database. Here is the code before i fix the deprecation. Any ideas what I'm doing wrong?
////////////////////Request Targeting A Specific Article///////////////////////
app.route("/articles/:articleTitle")
.get(function(req, res){
Article.findOne({title: req.params.articleTitle}, function(err, foundArticle){
if (foundArticle) {
res.send(foundArticle);
} else {
res.send("No articles with that title.");
}
});
})
/////////PUT PROBLEM MUST BE FIXED /////////////
.put(function(req, res){
Article.update(
{title: req.params.articleTitle},
{title: req.body.title, content: req.body.content},
{overwrite: true},
function(err){
if(!err){
res.send("succesfully updated");
}
}
);
})
///////PATCH PROBLEM MUST BE FIXED ///////////
.patch(function(req, res){
Article.update(
{title: req.params.articleTitle},
{$set: req.body},
function(err){
if(!err){
res.send("Successfully updated article.");
} else{
res.send(err);
}
}
);
});
app.route("/articles/:articleTitle")
.get((req, res) => {
Article.findOne({ title: req.params.articleTitle }, (err, result) => {
if (result) {
res.send(result);
} else {
res.send("err");
}
});
})
.put((req, res) => {
Article.replaceOne(
{ title: req.params.articleTitle },
{ title: req.body.title, content: req.body.content },
{ overwrite: true },
(err) => {
if (err) {
res.send("There is some error");
} else {
res.send("Updated successfully");
}
}
);
})
.patch((req, res) => {
Article.updateOne(
{ title: req.params.articleTitle },
{ $set: req.body },
(err) => {
if (err) {
res.send("There is some error");
} else {
res.send("Updated successfully");
}
}
);
});
Try this!! this will work fine.

Sending a POST request in Postman set to send a certain status sends the default status

I want that my POST request sends a HTTP 409 in a certain case, so this is the code:
res.status(409).send();
However, when I tun the request in Postman it shows the result 200 OK. I put some logs in the code and I'm sure that the above line is hit.
What is wrong?
UPDATE:
Here is the full method:
app.post('/orders/:order_id/sync_status', (req, res) => {
order.findOne({ order_id: req.params.order_id},
function(err, results) {
if (err) {
res.send(`error: ${error}`);
} else if (!results) {
res.send(`no order with order_id: ${req.params.order_id}`);
} else {
status.findOne({ order_id: req.params.order_id},
function(err, result) {
if (err) {
res.send(`error: ${error}`);
} else if (result) {
res.status(409).send();
} else {
const newStatus = new status (req.body);
newStatus.save();
}
});
}
res.end();
});
});
and the Postman request:
The simple reason is because you have res.end()
The longer answer is because res.end() is executed before this piece
status.findOne({order_id: req.params.order_id}, function(err, result) {
if (err) {
res.send(`error: ${error}`);
} else if (result) {
res.status(409).send();
} else {
const newStatus = new status(req.body);
newStatus.save();
}
});
got executed due to asynchronous call/callback.
Without testing, your final code should look like this
app.post('/orders/:order_id/sync_status', (req, res) => {
order.findOne({order_id: req.params.order_id}, function(err, results) {
if (err) {
return res.send(`error: ${error}`);
}
if (!results) {
return res.send(`no order with order_id: ${req.params.order_id}`);
}
status.findOne({order_id: req.params.order_id}, function(err, result) {
if (err) {
return res.send(`error: ${error}`);
}
if (result) {
return res.status(409).send();
}
const newStatus = new status(req.body);
newStatus.save();
return res.end();
});
});
});

how to get multiple collection data in single get method using mongoose in node js

router.post('/user', function (req, res) {
try {
MongoClient.connect("mongodb://test123:test123#localhost:27017/test", function (err, db) {
db.collection('user').findOne({ _id: req.body.UserId }, function (err, founddata) {
if (err) {
} else {
if (founddata) {
db.collection('project').find({ userId: founddata._id }, function (err, data) {
if (err) {
console.log(err);
} else {
console.log(data)
}
})
}
}
})
})
} catch (e) {
console.log(e)
}
})
I have tried many time but i geting error for second query is not run.output is null value.

node.js | Redis cache loading old data

I am trying to setup a mongo, node and redis server and all is working well other than the Redis cache which seemingly loads the older data.
Taking Redis out and using pure Mongo returns the right data, and if I click submit again it will load the data from the previous submission, so I know the cache and Mongo is updating fine.
This is the current code I have for updating the user using Mongo and Redis...
updateUserById: (newUser, redis, id, callback) => {
User.findByIdAndUpdate(id, {
$set: {
"firstName": newUser.firstName,
"lastName": newUser.lastName,
"email": newUser.email
}
}, (err, doc) => {
if (err) { throw new Error(err); }
else if (!doc) { callback('No user with that ID to update cache.') }
else {
redis.set(id, JSON.stringify(doc), (err) => {
console.log('Caching updated user ' + id);
if (err) { callback(err); throw new Error(err); }
else {
const result = {
"success": "true",
"message": "User updated successfully"
};
callback(result);
}
})
}
});
}
And this is the redis and Mongo to return the user information...
userById: async (redis, id, callback) => {
redis.get(id, async (err, reply) => {
if (err) {
callback(null); throw new Error(err);
} else if (reply) {
callback(JSON.parse(reply));
} else {
await User.findById(id, (err, doc) => {
if (err || !doc) { callback(null); throw new Error(err); }
else {
redis.set(id, JSON.stringify(doc), () => {
callback(doc);
})
}
})
}
})
}
I have found out it's something to do with the doc containing the old information in the updateUserById
The issue was inside of the update method.
When the doc was being passed, it was being passed the old data not the new data. To counter act this I used the newUser which was passed into the method.
Here is the updated code:
updateUserById: (newUser, redis, id, callback) => {
User.findByIdAndUpdate(id, newUser, (err) => {
if (err) { throw new Error(err); }
else {
redis.set(id, JSON.stringify(newUser), (err) => {
console.log('Caching updated user ' + id);
if (err) { callback(err); throw new Error(err); }
else {
const result = {
"success": "true",
"message": "User updated successfully"
};
callback(result);
}
})
}
});
}
Using new option can be useful to return new document.
Mongo return old document by default after update.
To return new document mongo option new may be useful
usage: Model.findByIdAndUpdate(id, update, {new: true});
updateUserById: (newUser, redis, id, callback) => {
User.findByIdAndUpdate(id, {
$set: {
"firstName": newUser.firstName,
"lastName": newUser.lastName,
"email": newUser.email
}
},{ new : true }, (err, doc) => {
if (err) { throw new Error(err); }
else if (!doc) { callback('No user with that ID to update cache.') }
else {
redis.set(id, JSON.stringify(doc), (err) => {
console.log('Caching updated user ' + id);
if (err) { callback(err); throw new Error(err); }
else {
const result = {
"success": "true",
"message": "User updated successfully"
};
callback(result);
}
})
}
});
}

Value not being updated in DB, node.js and mongoose

I am trying to update the value of my model and it does not work.
The weird thing is that I am printing out the result and it looks different than what I see in my database by using Robomongo.
Any thoughts why this happens?
Here is my code:
exports.create = function(req, res) {
var productId = req.query.product;
if (productId) {
Request.createWizard(req.user, { productId: productId }, function(err, request) {
Product.findById(productId, function(err, product) {
if (err) {
return console.log('oh no! error', err);
} else {
if (product.price =! 0 )
request.status = 'ready';
console.log(request);
(Here I see in the terminal: status = ready)
}
});
req.flash('success', { msg: 'Your request has been successfully created.' });
res.redirect('/discover');
});
} else {
var pages = require('../../schemas/wizard/request')();
res.render('requests/form', {
title: 'Make a Request',
pages: pages,
saveState: false
});
}
};
When I am checking the database status is still on pending.
You're changing the status property, but you're not saving the document back to the database after doing so:
Request.createWizard(req.user, { productId: productId }, function(err, request) {
Product.findById(productId, function(err, product) {
if (err) {
return console.log('oh no! error', err);
} else {
if (product.price !== 0) {
request.status = 'ready';
request.save(function(err) { // <-- save it back to the database
if (err) {
console.log('oh no! error', err);
} else {
console.log(request);
}
});
}
}
});
req.flash('success', { msg: 'Your request has been successfully created.' });
res.redirect('/discover');
});

Resources