0

I would like to filter an array based on a mongoose query. However, I am relatively new to node.js and asynchronous programming. I am aware that Array.prototype.filter is a synchronous function and the mongoose queries are asynchronous.

When searching on this site I came across the following two solutions:

  1. filtering an array with a function that returns a promise - but this looks quite complicated and I don't understand the concept yet.

  2. how to wait for the result of a mongoose query? - at first this solution looks quite understandable, so I gave it a try

here is my example code based on the second approach:

exports.create = function(req, res) {
    async.filter(req.body.data.entries, function(item, callback){
        MyCollection.findOne({'_id': item.id}, function(err, doc) {
            callback(err == null && doc != null);
        });    
    }, 
    function(results){
        req.body.data = results
        // default controller to create a document in Mongo DB
        return controller.create(Model, req, res);
    });
};

However, this does not seem to work. results does not correspond to a filtered list as described in the answer, but corresponds exactly to the result of the Boolean expression of the callback function. I also checked this in the current async documentation to see if anything has changed in the filter function, but didn't see any change.

Ben
  • 254
  • 3
  • 9
nlang
  • 3
  • 2
  • can you please explain your goal? Do you want to do a mongoose lookup for every element in your array `req.body.data.entries` and these lookups are not dependent on each other. is that right? – Raghav Garg Sep 13 '18 at 16:20
  • My intention is to filter out incorrect entries. The data from `req.body.data.entries` is like sensor data that could contain either a sensor entry that may no longer be registered or sensors from another network. So the lookups are not dependent on each other. – nlang Sep 14 '18 at 14:29

1 Answers1

1

Well, There is another way to do it. Instead of getting rows in async. You can get all the records filtered from database. There is a concept of $in in mongodb. You can use this to retrieve multiple records at a time with specific Ids. In your case, here is the exmaple

exports.create = function(req, res) {
    var ids = []
    req.body.data.entries.forEach(function (item) {
      ids.push(item.id);
    });
    MyCollection.findOne({'_id': {$in: ids}}, function (err, docs) {
      // here you have all your filter data
      var myDocs = docs;

      //Callback from here to return data
    });

  }
ManishKumar
  • 1,476
  • 2
  • 14
  • 22
  • Thanks for helping me out. I finally filtered the `req.body.data.entries` with the result from `docs`. – nlang Sep 14 '18 at 14:56