Search code examples
javascriptarraysajaxsuperagent

How to wait for all superagent calls to complete before reaching the end of the function


I am trying to make multiple api calls which are dynamically created from some input, the issue is that the method ends prior to the completion of all Ajax calls. I need to trigger an additional function to use the resulting json values from the Api calls following all results being achieved.

I am pretty sure, I am probably using promises incorrectly, or getting confused on them most certainly, I am still trying to get the hang of them, but can't get my head around this issue. All help greatly appreciated.

The fields() function should return an array of objects containing similar to the below 2 objects.

{"title":"Businessunit",
 "content":
    {"filter":
        {
            "fields":{"businessunitid":true,"settingsid":true,"archived":true}
        }
    }
}

{"title":"Address",
 "content":
    {"filter":
        {
            "fields":{"addressid":true}
        }
    }
}

function Export()
{
        queryGroup = fields();

        const response = async.map(queryGroup, a=>ApiCall(a), 

                    function(err, results) {
                        return results;
                    });
        return response;

}

async function ApiCall(lookup)
{
    console.log("LOOKUP: " + JSON.stringify(lookup));
    var table = new Object();

        superagent
        .get(document.getElementById("ApiEndPoint").value+'/api/'+document.getElementById("ApiKey").value+'/'+lookup.title)
        .query(lookup.content)
        .set('accept', 'json')
        .then(res => 
        { 
            table["Body"] = res.body
            table["Name"] = lookup.title;

            console.log("completed: "+ lookup.title);

            return table;
        }).then(table => {return Promise.resolve(table);});

}




Solution

  • Your Export should return a Promise.all once all apiCalls are processed. Create the object to be returned inside the last .then in apiCall, so that the Promise chain resolves to that object.

    Because export is a reserved keyword, it would probably be a good idea to use a different name for that function, like getAllFieldInfo or something of the sort:

    function getAllFieldInfo() {
      return Promise.all(fields().map(apiCall));
    }
    
    function apiCall(lookup) {
      const superagentGetParam = document.getElementById("ApiEndPoint").value + '/api/' + document.getElementById("ApiKey").value + '/' + lookup.title;
      return superagent
        .get(superagentGetParam)
        .query(lookup.content)
        .set('accept', 'json')
        .then(res => ({
          Body: res.body,
          Name: lookup.title
        }));
    }