0

i am trying to push the resultant of the count to an array in mogodb query, while pushing it showing the array after that if print it outside of query it is showing empty array.

collection1 in db is like below

[{title:Home,
  date:24-10-2016},
  {title:Accesories,
   date:13-02-2016}
]

my code

exports.listOfCategories=function(req,res){
     collection1.find().exec(function (err, categories) {
        if (err) {
          return res.status(400).send({
            message: errorHandler.getErrorMessage(err)
          });
        } else {
          var categoryList = categories;
          var catTitle;
          var allCat = [];
          // console.log(categoryList);
          for (var i = 0; i < categoryList.length; i++) {
            catTitle = categoryList[i].title;
            contentCounts(catTitle);     

            function contentCounts(content, callback) {
              var catName = new RegExp(content, 'i');
              var mongoQuery = {
                  "ProCategory.title": catName
                }

              collection2.find(mongoQuery).count(function (err, count) {            
                generateContentArr(content, count)
              });
            }


            function generateContentArr(content, count) {
              allCat.push({
                name: content,
                count: count
              });
              console.log(JSON.stringify(allCat));
              // Here it is showing the array what i pushed 

            }

          }
          console.log(JSON.stringify(allCat));
           // Here it not showing the total array, it showing an empty array

          res.json(allCat);
        }
      });
}

Thanks in advance

1 Answer 1

1

You are not waiting for the result of an async operation, in your case in the for loop you need to wait for the result of mongo operation, but as for loop is synchronous, you are just making calls to mongo but don't wait for the results, and print the empty array right after the loop.

I would suggest you to use promises instead of callbacks, I don't know which version of mongoose you are using but the last version have promise support for mongo methods like find and count. Here is an example for your case:

var Promise = require("bluebird");

function countByTitle(catTitle){
    var mongoQuery = {"ProCategory.title": new RegExp(catTitle, 'i')}
    return collection2.count(mongoQuery).then(function(count) {
        return {
            name: catTitle,
            count: count
        };
    });
}

collection1.find().then(function (categories) {
    var categoryList = categories;
    var promises = [];
    for (var i = 0; i < categoryList.length; i++) {
        promises.push(countByTitle(categoryList[i].title));
    }
    return Promise.all(promises).then(results => {
        console.log(JSON.stringify(results));
    })
}).catch(function (err) {
    //if there is any error while resolving the promises, this block will be called
    return res.status(400).send({
        message: errorHandler.getErrorMessage(err)
    });
});
Sign up to request clarification or add additional context in comments.

7 Comments

In result the count was coming good what i expected but the same name was coming for all the objects [{name:home,count:20},{name:home,count:3},{name:home,count:12}] like this it showing the same name for all @cubbuk
@Midhunsai I moved the logic inside a function so you will receive correct name for each promise. Btw it would be better if you move mongo operations into another module where you handle the business logic, and extract only that function. Then in this file you can only call this method, then return http response according to the result.
thanks for reply it is coming good as what i expected but after that i want to send it to response ie., send it to the client side because i am doing this in my server side, while iam trying to send the results to response like this return Promise.all(promises).then(results =>{ res.json(results); }) it is not sending to response, i have edited my question in the last i want to send it to reponse see once @cubbuk
what library do you use, usually you send response like res.send(200, {results: results})
can you please explain me to where we are returning, why we are returning like this return Promise.all(promises).then(results =>{ console.log(JSON.stringify(results)); }) @cubbuk
|

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.