async.js waterfall in node.js: how to use bind and this?

I'm learning node.js coming from a PHP background with a limited JavaScript level. I think I got over now the change of mindset implied by the asynchronous approach. And I love it.

But, as many others before me, I quickly understood the concrete meaning of the "pyramid of doom".

So I build these little 'dummy' route and view to understand how to properly use Async.js. I just spend the last 5 hours writing the following code (rewritten of course tens of times). It works, but I wonder how I could go further and made this code more simple (less verbose, easier to read and maintain).

I found many resources on the web and especially here, but always by bits of info here and there.

I'm guessing at this point that I should use "bind" and "this" with async.apply to make to shorten the 2 last functions called by the waterfall.

The issue is to get the object "db" defined so I can use the "collection" method on it (for the second function).

I really searched an example in Google, but it's surprising that you don't get straightforward examples looking for "async waterfall bind" (as well as many keyword variations I tried). There are answers of course but none seems relevant to this particular issue... ore, quite possibly, I haven't understood them.

Can someone help me on this? I'll be quite grateful.

app.get('/dummy',

    function(req, res) {

        var MongoClient = require('mongodb').MongoClient;

        async.waterfall(
            [
                async.apply(MongoClient.connect, 'mongodb://localhost:27017/mybdd'),

                function(db, callback) {
                    db.collection('myCollection', callback);
                },

                function(collection, callback) {
                    collection.find().sort({"key":-1}).limit(10).toArray(callback);
                }

            ], function(err, results) {
                if (err) console.log('Error :', err);
                else { res.render('dummy.jade', { title:'dummy', results: results} ); }
            }
        );

    }

);

If you're using the mongodb JS Driver, then this should work:

async.waterfall(
            [ 
             function (cb) {
               new MongoClient(...)
               .connect('mongodb://localhost:27017/mybdd', cb);
             },

             function (db, callback) {
               db.collection('myCollection', callback);
             },
...

Alternatively, if you want to use async.apply, just pass an instance of MongoClient

async.apply(new MongoClient(...).connect, 'mongodb://localhost:27017/mybdd')

I've recently created a simple abstraction named WaitFor to call async functions in sync mode (based on Fibers): https://github.com/luciotato/waitfor

I'm not familiar with mongodb client, so i'll be mostly guessing what you're trying to do:

using WaitFor your code will be:

var MongoClient = require('mongodb').MongoClient;
var wait = require('waitfor');

app.get('/dummy', function(req, res) { 

       // handle request in a Fiber, keep node spinning
       wait.launchFiber(handleDummy,req,res) 

       }
);


function handleDummy(req, res) {
    try {
        var db = wait.for(MongoClient.connect, 'mongodb://localhost:27017/mybdd');
        var collection = wait.forMethod(db,'collection','myCollection');
        var results = wait.forMethod(collection.,'sort',{"key":-1}).toArray();
        res.render('dummy.jade', { title:'dummy', results: results} );
    }
    catch(err) {
        res.render('error.jade', { title:'error', message: err.message} );
    }
};