FRizal
FRizal

Reputation: 448

Async waterfall with mongo db

Probably just a basic concept of async. I'd like to check on how we can pass the array variable from mongo result(docs) to the second function. In below code the second console.log doesn't give any output.

// Retrieve
var db = require('monk')('localhost/db');
var async = require('async');

console.log('start');

async.waterfall([

    function(callback) {
        var test = db.get('test');
        test.find({}, function(err, docs) {
            console.log(docs);  //OUTPUT OK
            callback(docs);  

        });

    },
    function(docs, callback) {
        console.log(docs);  //NO OUTPUT
    }
])

Upvotes: 2

Views: 2068

Answers (2)

chridam
chridam

Reputation: 103345

To give you a better understanding of the using multiple callbacks with the async module, let's illustrate this with an example from Seven Things You Should Stop Doing with Node.js of multiple operations with callbacks to find a parent entity, then find child entities that belong to the parent:

methodA(function(a){
    methodB(function(b){
        methodC(function(c){
            methodD(function(d){
                // Final callback code        
            })
        })
    })
})

With the async module, you can either use the series method to address the use of callbacks for nesting code of multiple methods which may result in Callback Hell:

Series:

async.series([
    function(callback){
        // code a
        callback(null, 'a')
    },
    function(callback){
        // code b
        callback(null, 'b')
    },
    function(callback){
        // code c
        callback(null, 'c')
    },
    function(callback){
        // code d
        callback(null, 'd')
    }],
    // optional callback
    function(err, results){
        // results is ['a', 'b', 'c', 'd']
        // final callback code
    }
)

Or the waterfall:

async.waterfall([
    function(callback){
        // code a
        callback(null, 'a', 'b')
    },
    function(arg1, arg2, callback){
        // arg1 is equals 'a' and arg2 is 'b'
        // Code c
        callback(null, 'c')
    },
    function(arg1, callback){      
        // arg1 is 'c'
        // code d
        callback(null, 'd');
    }], function (err, result) {
        // result is 'd'    
    }
)

Now going back to your example, using the async waterfall method you could restructure your code to

async.waterfall([
    function(callback) {
        // code a
        var test = db.get('test');
        test.find({}, function(err, docs) {
            if(err) callback(err);

            console.log(docs);  // OUTPUT OK
            callback(null, docs);                                    
        });
    }], function(err, result) {
        if(err) callback(err);
        console.log(result);  // OUTPUT OK
    }
])

Upvotes: 5

Vishnu
Vishnu

Reputation: 12293

You must always handle your errors. Try this!

// Retrieve
var db = require('monk')('localhost/db');
var async = require('async');

console.log('start');

async.waterfall([

    function(callback) {
        var test = db.get('test');
        test.find({}, function(err, docs) {
            if(err){
                console.log(err);
                callback(err);
            }
            else if(docs){
                console.log(docs);
                callback(null,docs);
            }
            else{
                console.log("No error no docs");
                callback(null);
            }

        });

    },
    function(err, docs) {
        if(err)
           console.log(err);
        else{
           console.log(docs);
        }
    }
])

Upvotes: 1

Related Questions