GoldfishGrenade
GoldfishGrenade

Reputation: 631

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]}

Upvotes: 2

Views: 563

Answers (2)

Oleksandr T.
Oleksandr T.

Reputation: 77482

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);
  });
}

Upvotes: 2

vladzam
vladzam

Reputation: 5908

As Alexander mentioned in his comment, if you want to pass the values from the first function to the next one, you should use waterfall instead of series.

As specified in the official documentation regarding waterfall:

Runs the tasks array of functions in series, each passing their results to the next in the array. However, if any of the tasks pass an error to their own callback, the next function is not executed, and the main callback is immediately called with the error.

If you would like to read more about the various capabilities of async I strongly recommend their official documentation (LINK).

Upvotes: 1

Related Questions