nodejs async.waterfall method

Update 2

Complete code listing

var request = require('request');
var cache = require('memory-cache');
var async = require('async');

var server = '172.16.221.190'
var user = 'admin'
var password ='Passw0rd'
var dn ='\\VE\\Policy\\Objects'

var jsonpayload = {"Username": user, "Password": password}


async.waterfall([
    //Get the API Key
    function(callback){
        request.post({uri: 'http://' + server +'/sdk/authorize/',
                json: jsonpayload,
                headers: {'content_type': 'application/json'}
            }, function (e, r, body) {
            callback(null, body.APIKey);
        })
},
    //List the credential objects
    function(apikey, callback){
        var jsonpayload2 = {"ObjectDN": dn, "Recursive": true}
        request.post({uri: 'http://' + server +'/sdk/Config/enumerate?apikey=' + apikey,
                json: jsonpayload2,
                headers: {'content_type': 'application/json'}
        }, function (e, r, body) {

            var dns = [];
            for (var i = 0; i < body.Objects.length; i++) {
                dns.push({'name': body.Objects[i].Name, 'dn': body.Objects[i].DN})
            }

            callback(null, dns, apikey);
        })

    },
    function(dns, apikey, callback){
      //  console.log(dns)

        var cb = [];

        for (var i = 0; i < dns.length; i++) {

        //Retrieve the credential
        var jsonpayload3 = {"CredentialPath": dns[i].dn, "Pattern": null, "Recursive": false}
            console.log(dns[i].dn)
        request.post({uri: 'http://' + server +'/sdk/credentials/retrieve?apikey=' + apikey,
            json: jsonpayload3,
            headers: {'content_type': 'application/json'}
        }, function (e, r, body) {
         //   console.log(body)
            cb.push({'cl': body.Classname})
            callback(null, cb, apikey);
            console.log(cb)
        });
        }


    }
], function (err, result) {
//    console.log(result)
    // result now equals 'done'
});    

Update:

I'm building a small application that needs to make multiple HTTP calls to a an external API and amalgamates the results into a single object or array. e.g.

  1. Connect to endpoint and get auth key - pass auth key to step 2
  2. Connect to endpoint using auth key and get JSON results - create an object containing summary results and pass to step 3.
  3. Iterate over passed object summary results and call API for each item in the object to get detailed information for each summary line
  4. Create a single JSON data structure that contains the summary and detail information.

The original question below outlines what I've tried so far!

Original Question:

Will the async.waterfall method support multiple callbacks?

i.e. Iterate over an array thats passed from a previous item in the chain, then invoke multiple http requests each of which would have their own callbacks.

e.g,

sync.waterfall([

   function(dns, key, callback){

       var cb = [];

       for (var i = 0; i < dns.length; i++) {

       //Retrieve the credential
       var jsonpayload3 = {"Cred": dns[i].DN, "Pattern": null, "Recursive": false}
           console.log(dns[i].DN)
       request.post({uri: 'http://' + vedserver +'/api/cred/retrieve?apikey=' + key,
           json: jsonpayload3,
           headers: {'content_type': 'application/json'}
       }, function (e, r, body) {
           console.log(body)
           cb.push({'cl': body.Classname})
           callback(null, cb, key);

       });
       }


   }

Let's hope I understood your question correctly. It seems to me you want to call the api for each item in dns and need to know when they're done. async.waterfall is typically used when you have a chain of functions which uses the result of the preceding function. In your case I can only see that you need to use the result from all of the api-calls in one callback. And since you also want to create a new array I would use async.map.

Update:

If you want to make a loop inside an async.waterfall, async.each/map is the weapon of choice. The code below will call the waterfall-callback when each dns has been called.

async.waterfall([
  // ...,
  function(dns, apikey, callback){
    async.map(dns, function (item, next) {
      var jsonpayload3 = {
        Cred: dns[i].DN,
        Pattern: null,
        Recursive: false
      };

      request.post({
        uri: 'http://' + vedserver +'/api/cred/retrieve?apikey=' + key,
        json: jsonpayload3,
        headers: {'content_type': 'application/json'}
      }, function (e, r, body) {
        next(e, { cl: body.Classname });
      });
    },
    callback);
  }],
  function (err, result) {
    // result now looks like [{ cl: <body.Classname> }]
  });