2

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.

4 Answers 4

3

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.

Sign up to request clarification or add additional context in comments.

Comments

2

@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]));
}

Comments

2

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')
  }
)

Comments

0

Using Q library

  var Q = require('q')
    var i = 0;

    function hello (item){

       var defer = Q.defer();

        Issue.count({'section.name': student}, function (err, count) {
               if(err){

                 defer.reject(err);

                }else{

                 var result = 'Section name is: ' + item + ' number of employees: ' + count ;
                 defer.resolve(result)

                 }

            });

    })
           return defer.promise;
      }


      function recall(){
        hello(checkItems[i]).then((val)=>{
          console.log(val)
          if(i < checkItems.length - 1){
            i++
            recall();
          }
        })
      }
    recall()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.