Reputation: 1310
I'm trying to send my node server multiple entries in order to update every person inside the database.
I thought a way to do it would be to loop through each person through their unique Ids and save the updated information based on this.
However, inside the Employee.findById function I cannot access the value of [i]
so I cannot get the relevant employee. Running this line of code when trying to modify 2 Employees var i
will output;
router.patch('/edit', function(req, res, next) {
for (var i = 0; i < req.body.length; i++) {
console.log("outside " + i)
Employee.findById(req.body[i].employeeId, function(err, employee) {
console.log("inside " + i)
/*
employee = new Employee({
name: req.body[i].name,
})
employee.save();
*/
})
}
})
I'm not sure why the console.log("inside " + i)
isn't outputting the same number as the outside log?
Also, I'm not sure if the approach I am taking is the correct way of doing this?
Thanks for any advice!
Upvotes: 0
Views: 931
Reputation: 2313
It's because the function findById()
is asynchronous. The iteration of the loop doesn't wait findById()
terminated the query.
I suggest you in order to fix this problem to use the lib Async.
It's provide some useful methods for doing things in asynchronous and wait the response.
In your case something like that can fix the problem:
async.each(req.body, function (value, callback) {
Employee.findById(value.employeeId, function(err, employee) {
employee = new Employee({
name: value.name,
})
// The callback indicate that this iteration is terminated.
employee.save(callback);
});
}, function (err) {
// When all callback() are triggered we pass here, and this tells we finished all operation.
});
I suggest you to read carefully the documentation of each
Upvotes: 1
Reputation: 1018
When your /edit
route is called, the for loop runs, logs out the "outside"
statement and calls the Employee.findById
method for each element in req.body
, which will execute and call the "inside"
console log statement when the find operation has finished. Note that this is an asynchronous operation.
The i
variable does not change inside the callback of the Employee.findById
call. This is because the for loop already incremented i
to the number of elements in req.body
.
By doing this, you will not be able to tell if all operations finished or an error occured while saving the employee documents and forward this information to the client in the response.
I would suggest using async or another flow controll library.
Your example using async
:
router.patch('/edit', function(req, res, next) {
async.each(req.body, function(obj, cb) {
Employee.findById(obj.employeeId, function(err, employee) {
if (err) {
return cb(err);
}
employee = new Employee({name: obj.name});
employee.save(cb);
});
}, function (err) {
// any errors from callback will be handled here
// inform you user in the response or whatever
});
});
Upvotes: 2