the nested function is not performed NodeJS, Mongoose - javascript

I have created a function that is looking for any reservation document with matching _id, if exists is deleted, and next the Book(findById) function is performed which is looking for any books using function(findOneAndUpdate), if exists is added value to quantity +1.But i don't know why but the function does not want to be done.
router.post('/cancel-reservation', (req, res) => {
var reservation = req.body.reservation;
Reservation.findByIdAndRemove(reservation._id, function (err) {
if (err) throw err;
else {
Book.findById(reservation.idBook, (err, book) => {
if (err) throw err;
if (book == null) {
//////////// //*WORKING *////////////////
let bookObj = {
name: reservation.nameBook,
description: reservation.description,
publishingHouse: reservation.publishingHouse,
quantity: 1,
year: reservation.year,
sites: reservation.sites
};
var book = new Book(bookObj);
book.save()
.then(function (book) {
res.json(book)
})
.catch((err) => {
res.json('not saved')
})
//////////// //*WORKING *////////////////
} else if (book) {
// findOneAndUpdate
//////////// //*HERE IS PROBLEM *////////////////
book.quantity = book.quantity+1;
console.log(book._id)
Book.findOneAndUpdate({ _id: book._id },
{ $set: { quantity : book.quantity } }, { upsert: true }),
((err, complete) => {
if(err) console.log('errrrrr');
else {
console.log(complete)
console.log('complete')
res.json(complete)
}
})
}
});
}
});
});
this problem may be related to the fact that the findOneAndUpdate function is nested in findById?

I think that you have an extra parentheses on the findOneAndUpdate
Book.findOneAndUpdate({ _id: book._id },
{ $set: { quantity : book.quantity } }, { upsert: true },
(err, complete) => {
if(err) console.log('errrrrr');
else {
console.log(complete)
console.log('complete')
res.json(complete)
}
})

Related

Can't Understand code execution order Javascript

I am learning mongoose and I'm unable to understand some code execution order of javascript
Code:
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/fruitsDB");
const fruitSchema = new mongoose.Schema({
name: {
type: String,
required: [true, "Please check your data entry, no name specified!"],
},
rating: {
type: Number,
min: 1,
max: 10,
},
review: String,
});
const Fruit = mongoose.model("Fruit", fruitSchema);
// Reading data from database
Fruit.find((err, fruits) => {
if (err) {
console.log(err);
} else {
// console.log(fruits);
mongoose.connection.close();
fruits.forEach((fruit) => {
console.log(fruit.name);
});
}
});
// Updating data in database
Fruit.updateOne({ name: "Kiwi" }, { name: "Peach" }, (err) => {
if (err) {
console.log(err);
}
else {
console.log("Successfully updated data");
}
});
// Deleting data in database
Fruit.deleteOne({ name: 'Peach' }, (err) => {
if (err) {
console.log(err);
}
else {
console.log('Data deleted successfully');
}
})
console.log output:
I am unable to understand why the Update function in running before the find() function, can anyone explain this to me please?

MongoDB/Mongoose $pull an Object in an Array where _id of the Object is matching

I have this Schema here
Consider the likedTours which is an Array of Objects (Tours) (ignore position 0).
I want to pull any Objects where the _id of a Tour matches the critiria.
Adding a new Tour upon liking a tour is okay, but on unlike I don't know how to pull that item out.
Here is my function in the Controller in the Node.JS backend
const unlikeTour = async (req, res) => {
try {
TourDB.Tour.findOneAndUpdate(
{ _id: req.params.tourid },
{
$pull: { likedUsers: req.userID },
$inc: { likes: -1 },
}
).exec(async (err, docs) => {
if (!err) {
try {
await UserDB.User.findOneAndUpdate(
{ _id: req.userID },
{ $pull: { 'likedTours._id': docs._id } } //Here I need help
).exec()
return res.status(200).send({ successMessage: 'Tour successfully unliked' })
} catch (err) {
return res.status(500).send({ errorMessage: 'User not found' })
}
} else {
return res.status(500).send({ errorMessage: 'Tour not found' })
}
})
} catch (err) {
return res.status(500).send({ errorMessage: err })
}
}
This method looks for a tour and update it by pulling out the userID and decrement the likes count by -1.
And then I try to find in the UserDB that tour in the likedTours and tried to pull but it doesn't not work like that.
Thanks in advance
you can update as
await UserDB.User.findOneAndUpdate(
{ _id: req.userID },
{ $pull: { likedTours: { _id: docs._id } } } //Here I need help
).exec();
reference: https://docs.mongodb.com/manual/reference/operator/update/pull/

Issue on autoIncrementing a value using findOneAndUpdate in MongoDB/Node.js

Well, I am trying to do autoincrement in node.
So I have a simple function that I found here How to add auto increment to existing collection in mongodb/node.js?
// Increment DB Value
exports.getNextSequenceValue = async function (sequenceName) {
try {
const seqNum = await db.collection('counters').findOneAndUpdate({
_id: sequenceName
}, {
$inc: {
seq: 1
}
}, {
returnNewDocument: true
});
// Check if response has seqNum.seq exists
console.log(seqNum.value.seq);
if (seqNum && seqNum.value.seq) {
return seqNum.value.seq
} else {
return 'what ever you want '
}
} catch (err) {
console.error(err)
}
}
and my controller where i used it.
const user = new User({
profile: {
firstname: req.body.firstname,
lastname: req.body.lastname,
location: req.body.location,
status: 1,
avatar: "/uploads/avatars/defaultProfilePic.jpg"
},
email: req.body.email,
password: req.body.password,
xid: core.getNextSequenceValue('userid') // ----HERE ITS FUNCTION-----
});
console.log(core.getNextSequenceValue('userid')) //---- [object Promise]X ---
User.findOne({
email: req.body.email
}, (err, existingUser) => {
if (err) {
return next(err);
}
if (existingUser) {
req.flash('errors', {
msg: 'Account with that email address already exists.'
});
return res.redirect('/signup');
}
user.save((err) => {
if (err) {
return next(err);
}
req.logIn(user, (err) => {
if (err) {
return next(err);
}
res.redirect('/');
});
});
});
};
But now i get error.
ValidationError: User validation failed: xid: Cast to Number failed for value "Promise { <pending> }" at path "xid"
Have no idea how to fix it.
Thanks for any help.
Ok your issue seems to be with new : true when you're using findOneAndUpdate(), it has to be returnNewDocument: true more over you need to do await on function which takes sometime to finish but not on the response of it. Remember to always wrap your async & await with try-catch block.
exports.getNextSequenceValue = async function (sequenceName) {
try {
const seqNum = await db.collection('counters').findOneAndUpdate({
_id: sequenceName
}, {
$inc: {
seq: 1
}
},
{ returnNewDocument: true }
);
// Check if response has seqNum.seq exists
console.log(seqNum.seq);
if (seqNum && seqNum.seq) { return seqNum.seq } else {
return 'what ever you want '
}
} catch (err) {
console.error(err)
}
}

Callback/Promises implementation for a boolean check

Currently I have the following callback system:
var saveTask = function(err, result) {
if (err) return callback(err, result);
var newid = mongoose.Types.ObjectId();
var task = new Task({
_id: newid,
taskname: req.body.name,
teamid: req.body.team,
content: req.body.content,
creator: req.user.userId
});
task.save(function (err) {
if (!err) {
log.info("New task created with id: %s", task._id);
return callback(null, task);
} else {
if(err.name === 'ValidationError') {
return callback('400', 'Validation error');
} else {
return callback('500', 'Server error');
}
log.error('Internal error(%d): %s', res.statusCode, err.message);
}
});
};
if (req.body.team) {
valTeam.isMember(req.body.team, req.user._id, function (err, done) {
if (err) {
saveTask('403', 'Not the owner or member of this team');
} else {
saveTask(null, true);
}
});
} else {
saveTask(null, true);
}
valTeam.isMember
exports.isMember = function(teamid, userid, callback) {
Team.find({'_id':teamid, $or:[{'creator': userid }, {'userlist': { $in : [userid]}}]}, function(err, result) {
if (err) return err;
console.log(result);
if (!result.length)
return callback('404', false);
else
return callback(null, true);
});
}
In short, if team is sent by POST, I'm checking if the user is member of that ID in valTeam.isMember. Am I using the correct syntax and best method to call back my saveTask function to save the task if the user is part of the team?
This code currently works, but I feel like there should be an easier way to do it? How could I use a promise to achieve the same thing?
Thanks in advance.
It's curious the fact that you create objects instead Schemas. However "every head is a different world", this is my way:
task.save(function(error, data){
if (error) {
trow error;
} else {
//Make whatever you want here with data
});

Combine $push and save in mongoDB

Writing my pet application I met some problem. I'm using nodejs and mongojs library to work with mongo.
I wrote code:
db.users.findOne({_id: ObjectId(id)}, function (err, doc) {
if (err) {
res.status(500).send('Can not find name for user.');
return;
}
userName = doc.userName;
db.notes.findOne({userId: id}, function (err, doc) {
if (!doc) {
db.notes.insert({
userId: id,
userName: userName,
notes: [req.body]
}, function (err, doc) {
if (err) {
res.status(500).send('Server error.');
return;
}
res.json(doc);
});
} else {
db.notes.update({
userId: id
}, {
$push: {
'notes': req.body
}
},
function (err, doc) {
if (err) {
res.status(500).send('Server error.');
return;
}
res.json(doc);
});
}
if (err) {
res.status(500).send('Server error.');
return;
}
});
});
Now it looks like callback hell for me. I try to modify my code to make it more readable and use save method:
users.findOne({_id: makeObjectId(id)}, function (err, doc) {
if (err) {
res.status(500).send('Can not find name for user.');
return;
}
userName = doc.userName;
notes.save({
userId: id,
userName: userName
}, {
$push: {
'notes': req.body
}
}, function (err, doc) {
if (err) {
return res.status(500).send('Error during inserting the note');
}
res.status(200).send(doc);
});
});
Now it looks more readable but doesn't work. Is it possible in MongoDB to combine save method (to make it possible to modify document if it exists and create new if not) and $push for one of parameters?
Thanks in advance.
Bingo!!!
notes.update({
userId: id,
}, {
$set: {
userId: id,
userName: userName
},
$push: {
notes: req.body
}
}, {
upsert: true
}, function (err, doc) {
if (err) {
return res.status(500).send('Error during inserting the note');
}
res.status(200).send(doc);
});
Thanks to Blakes Seven

Categories