3

I have a NodeJS API using Express 4. I am using sequelize to connect to the database and I invoke one query many times. I want accumulate the results into an Array. The problem is that res.send doesn't wait for the loop to end to send the answer.

my code

router.post('/payrollReport/', function(req, res, next) {
    var usersRecord = [];
    models.user.findAll(
    ).then(function(users) {
      for (var i = 0; i < users.length; i++) {
            models.sequelize.query('SELECT forms.name, COUNT(form_submits.form_id)  ' +
                    'FROM form_submits ' + 
                    'LEFT JOIN forms ON forms.form_id = form_submits.form_id ' +
                    'WHERE form_submits.user_id = ' + users[i].user_id +
                    'AND date("form_submits"."createdAt") >=' + req.body.begin +
                    'AND date("form_submits"."createdAt") <=' + req.body.end +
                    " GROUP BY forms.name")
             .then(function(results){
                 usersRecord.push(results[0]);
                 console.log(usersRecord);
            });      
      };
    }).catch(function(error) {
      res.status(500).send(error);
    });  
    res.send(usersRecord);
});

thanks for your help

EDIT

Add the correct code using forEach

router.post('/payrollReport/', function(req, res, next) {
    var usersRecord = [];
    models.user.findAll(
    ).then(function(users) {
       async.forEachOf(users, function iterator(user, index, callback) {
            models.sequelize.query('SELECT forms.name, COUNT(form_submits.form_id)  ' +
                    'FROM form_submits ' + 
                    'LEFT JOIN forms ON forms.form_id = form_submits.form_id ' +
                    'WHERE form_submits.user_id = ' + user.user_id +
                    'AND date("form_submits"."createdAt") >=' + req.body.begin +
                    'AND date("form_submits"."createdAt") <=' + req.body.end +
                    " GROUP BY forms.name")
             .then(function(results){
                 results[0].unshift(user); 
                 usersRecord.push(results[0]);
                 callback();
            });   

         }, function (err) {
          if (err) console.error(err.message);
          res.send(usersRecord);
       });


    }).catch(function(error) {
      res.status(500).send(error);
    });  

});
3
  • Soooo... your question is what? You will likely need to store all you promisables into an array and use the Promise.all method, as to act only when all of your promises have been resolved. Commented Jan 4, 2016 at 17:03
  • you should chain your .then()'s and not have one inside another. Commented Jan 4, 2016 at 17:05
  • 3
    You want Promise.all(users.map(...)). Read blog.slaks.net/2015-06-10/advanced-promise-usage Commented Jan 4, 2016 at 17:06

1 Answer 1

5

Since node.js works asynchronously, your res.send(usersRecord); command is executed before all iterations are done. You can use async.foreach for this, it will allow you to run your send only after all iterations are done.

There's a great tutorial about it here

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

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.