Search code examples
node.jsnode-mongodb-native

How do I pass a variable into mongodb callback?


I'm trying to select the distinct values for two fields from my mongodb. Using async.series, I have the following:

function getSettings(target){
    var versions = [];
    var result = {};

    function putResults(key, val){
        result[key] = val;
    }
  async.series(
  [
    function(callback){
        db.get(target).distinct('version', function(err, arr){
            if(err) return err;
            versions = arr;
            callback();
        }); //end db call
    },
    function(callback){
        var items;
        for(var i = 0; i<versions.length; i++)
        {
            db.get(target).distinct('instance', {version: versions[i]}, function(err, arr){
                items = arr;
                putResults(versions[i], items);
            }); //end db call
         }
     }
  ], 
  function(err){
         if(err) return err;
         console.log(result);
  }); //end async
}

With this code, I get an "undefined" exception on putResults(versions[i], items). I know it's because versions is out of scope. My question is: how do I get it in scope?

Expected result:

 result = {1: [1, 2, 3], 2: [1, 2, 3, 4]}

Solution

  • In our case better use waterfall instead of series, and map, like this

    function getSettings(target){
      async.waterfall([
        function (callback) {
          db.get(target).distinct('version', function (err, versions) {
             callback(err, versions);
          });
        },
        function (versions, callback) {
          async.map(versions, function (version, next) {
            db.get(target).distinct('instance', {version: version}, function (err, items) {
              var result = {};
              result[version] = items;
              next(err, result);
            });
          }, function (err, res) {
            callback(err, res);
          });
        }
      ], function (err, result) {
        if (err) {
          return;
        } 
    
        console.log(result);
      });
    }