Trong Lam Phan
Trong Lam Phan

Reputation: 2412

Mongoosejs use promise in a for loop

I have two collections: question and answer. Each answer belongs to a question so an answer has its "question_id".

I like to get five questions which has most answers:

Answer.aggregate([
        {
            $group: {
                _id: '$question_id',
                num_questions: { $sum: 1 },
            }
        },
        {
            $sort: {
                'num_questions': -1
            }
        }
    ]).then(function(answers) {
        var result = [];
        for(answer of answers) {
            Question.findById(answer._id, function(err, question) {
                result.push(question);
            });
        }
        console.log(result);
        res.json({questions: result});
});

but with the above code, my result will be null because of the async mechanism.

How can I get it done ?

Another problem that I had, with the aggregate query, I can only have questions that has at least one answer. How can I get the questions without answer ?

Upvotes: 0

Views: 50

Answers (2)

Nico Van Belle
Nico Van Belle

Reputation: 5146

A better way would be using a Promise library like Q which helps you with these things. With Q it's easy to wait until all promises resolve without using extra shenanigans (like using a count variable)..

Answer.aggregate([
    {
        $group: {
            _id: '$question_id',
            num_questions: {$sum: 1}
        }
    },
    {
        $sort: {
            'num_questions': -1
        }
    }
]).then(function (answers) {
    var promises = [];
    for (answer of answers) {
        promises.push(Question.findById(answer._id).exec());
    }

    Q.all(promises).then(function(questions) {
        res.json({'questions': questions});
    });
});

Upvotes: 0

user5116395
user5116395

Reputation:

Answer.aggregate([
        {
            $group: {
                _id: '$question_id',
                num_questions: { $sum: 1 },
            }
        },
        {
            $sort: {
                'num_questions': -1
            }
        }
    ]).then(function(answers) {
        var result = [];
        var count = 0;
        for(answer of answers) {
            Question.findById(answer._id, function(err, question) {
         count++
                result.push(question);
       if (count == 5) {
        res.json({questions: result});
      }
            });
        }
        console.log(result);
});

Upvotes: 1

Related Questions