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);
}
})
}
});
}
Related
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)
`
I have this code:
MongoClient.connect(config.mongoURL, {useNewUrlParser: true}, (err, db)=> {
if (err) {
console.log("Err", err)
cb(-1)
}
else {
var con = db.db('englishAcademy')
try {
con.collection("sound").updateOne({"_id": new ObjectID(sndId)}, {
$set: {
"snd_title": info.snd_title,
"snd_type": info.snd_type,
"snd_url": info.snd_url,
"snd_lsnId": info.snd_lsnId,
"snd_lvlId": info.snd_lvlId,
"snd_order": info.snd_order
}
}), (err, doc) => {
console.log("result")
if (err) {
console.log(err)
cb(-1)
}
else {
console.log(doc)
let result = 'row affected'
cb(doc)
}
}
}
catch (e) {
console.log(e)
}
}
})
could anyone please tell me what is wrong with my code?the updateOne function does not return anything.but my mongo database gets updated.
EDIT :
I have done this so far and it did not worked.could anyone please help?I used assert no success.I used new :true, no success.I used finde and update ,no success
let infor = {
"adm_name": info.adm_name,
"adm_username": info.adm_username,
"adm_password": info.adm_password
}
con.collection("admins").findOneAndUpdate({"_id": new ObjectID(admId)}, {
$set: infor
},{new:true} ), (err , result) => {
console.log("result")
if (err) {
console.log(err)
assert.equal(err, null);
cb(-1)
}
else {
let result = 'row affected'
assert.equal(1, result.result.n);
}
set new: true
MongoClient.connect(config.mongoURL, {useNewUrlParser: true}, (err, db)=> {
if (err) {
console.log("Err", err)
cb(-1)
}
else {
var con = db.db('englishAcademy')
try {
con.collection("sound").updateOne({"_id": new ObjectID(sndId)}, {
$set: {
"snd_title": info.snd_title,
"snd_type": info.snd_type,
"snd_url": info.snd_url,
"snd_lsnId": info.snd_lsnId,
"snd_lvlId": info.snd_lvlId,
"snd_order": info.snd_order
},{new: true}
}), (err, doc) => {
console.log("result")
if (err) {
console.log(err)
cb(-1)
}
else {
console.log(doc)
let result = 'row affected'
cb(doc)
}
}
}
catch (e) {
console.log(e)
}
}
})
Try this way ..
collection.findOneAndUpdate(
{"_id": new ObjectID(sndId)},
$set: yourData },
{ new: true },
function (err, documents) {
res.send({ error: err, result: documents });
}
);
Now you can return newData in cb.
I want to increment id's automatically in the mongoDB while posting the data. I am able to attach date for the req.body. How to attach ids with auto incrementation?
This is my post call:
router.post('/addVisualization', function (req, res, next) {
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbo = db.db(dbName);
req.body.dateOfEntry = new Date();
function getNextSequence(id) {
var ret = db.counters.findAndModify(
{
query: { _id: id },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
dbo.collection("visualization").insertOne(req.body, function (err, resDB) {
if (err) {
throw err;
res.status(401);
res.send({
"status": 401,
"message": "Some error happened"
});
}
else {
console.log("1 document inserted");
res.status(201)
res.send({
"body": req.body,
"status": 201,
"message": "visualization has been added"
});
}
});
db.close();
});
});
Try out the below code to auto increment id's in mongoDB.
router.post('/addVisualization', function (req, res, next) {
MongoClient.connect(url, {
useNewUrlParser: true
}, function (err, db) {
if (err) throw err;
var dbo = db.db(dbName);
req.body.dateOfEntry = new Date();
req.body.isDeleted = "false";
var countRow;
var sequenceDocument = dbo.collection("counterVisualization").findOneAndUpdate({
_id: "tid"
}, {
$inc: {
sequence_value: 1
}
}, {
new: true
});
dbo.collection("counterVisualization").find({
_id: "tid"
}).toArray(function (err, result1) {
if (err) {
throw err;
} else {
countRow = result1[0].sequence_value;
req.body["_id"] = countRow;
dbo.collection("visualization").insertOne(req.body, function (err, resDB) {
if (err) {
throw err;
res.status(401);
res.send({
"status": 401,
"message": "Some error happened"
});
} else {
console.log("1 document inserted");
res.status(201)
res.send({
"body": req.body,
"status": 201,
"message": "visualization has been added"
});
}
});
}
});
});
});
In mongo db you don't have a auto increment ids as mysql or oracle, Please take a look at this tutorial for how to do it out of the box.
Use a separate counters collection to track the last id of the sequence.
db.counters.insert(
{
_id: "userid",
seq: 0
}
)
db.counters.insert(
{
_id: "productid",
seq: 0
}
)
Create a getNextSequence function that accepts a name of the sequence.
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true,
upsert : true // Creates a new document if no documents match the query
}
);
return ret.seq;
}
Use this getNextSequence() function during insert.
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Mr. X",
// ... more fields
}
)
db.products.insert(
{
_id: getNextSequence("productid"),
name: "Mr. Y",
// ... more fields
}
)
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.
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');
});