I am using NodeJS to count the number of employees in different section. I am using Mongoose as ODM and MongoDB as database.That is my code (very simple for testing purposes).
exports.list= function( req, res){
var array = ['sectionA', 'sectionB'];
var i;
for(i = 0; i<array.length; i++){
Issue.count({ 'section.name': array[i]}, function (err, count) {
console.log('Section name is: ' + array[i] + ' number of employees: ' + count );
)};
}
}
But the value of array[i] is undefined inside Issue.count({ 'section.name': array[i]}, function (err, count) {});. But the value of count is absolutely right. I want an output like:
Section name is: sectionA number of employees: 50
Section name is: sectionB number of employees: 100
But my current output is
Section name is: undefined number of employees: 50
Section name is: undefined number of employees: 100
This is because value of i inside Issue.count({ 'section.name': array[i]}, function (err, count) {}); is always 2.
Is it possible that Issue.count function is asynchronous? So your loop is completing before the callback of:
function (err, count) {
console.log('Section name is: ' + array[i] + ' number of employees: ' + count );
}
is executed. When the callbacks are executed the value of i is undefined as a result.
@eshortie is correct: Issue.count is asynchronous and that's causing the problem.
Here's a solution:
for (i = 0; i<array.length; i++) {
Issue.count({ 'section.name': array[i]}, function(sectionName, err, count) {
console.log('Section name is: ' + sectionName + ' number of employees: ' + count );
}.bind(null, array[i]));
}
Don't try to execute asynchronous functions using a regular for loop. It is asking for problems. Use async.eachSeries or async.each instead https://github.com/caolan/async#eachseriesarr-iterator-callback
var async = require('async')
var Issue = {} // mongoose isue model here
var elements = ['foo', 'bar']
async.eachSeries(
elements,
function(name, cb) {
var query = {
'section.name': name
}
Issue.count(query, function(err, count) {
if (err) { return cb(err) }
console.dir(name, count)
})
},
function(err) {
if (err) {
console.dir(err)
}
console.log('done getting all counts')
}
)