Search code examples
javascriptaxioses6-promise

Nested Axios Call Only Returns First Value to Array


I am nesting an Axios call in another in order to get the list of IDs from my first call and then loop through and for each ID get the status from a 2nd API call. It will only return the first status when I log the array, versus showing the full array.

I believe the issue may be in the promise chain... or if this is not waiting for the promises to complete before outputting the final array.

    var responsearray = [] 
    
    axios.get('https://myapi.net/api/role/allroles?pageSize=1000').then(function (response) {

    for(var i = 0; i < response.data.roles.length; i++)
    {
        var entry = response.data.roles[i];
        var entryid = entry.id;

        return axios.get('https://myapi.net/api/role/score/' + entryid).then(function (response2) {
               // Nested call per role to push to array
               responsearray.push(response2.status)
    });
    }

  }).catch(function (error) {
    // handle error
    console.log(error);

  }).then(function () {
    // always executed
        // Return Array
    console.log(responsearray);
  });

Solution

  • It looks like the outer promise is being resolved since you are returning a value (which is the first inner promise, the first Axios call inside the loop).

    Then, when the outer promise resolved, the outer then function is being called with the responsearray that happens to hold the result of the first response2 (however it might even be empty since the second Axios call may haven't been resolved yet).

    So the flow is something like that:

    First axios call => first Then is called => i=0, second axios call is **RETURNED** => first axios call is resolved => last then is called => (second axios may be resolved by now and responsearray is filled with the result for i=0) => console.log(responsearray)

    Anyway, I would suggest using Promise.all that gives you a promise that contains a collection of promises and resolve it only if all of the promises are resolved. You can read more about it here.

    I would use it something like that:

    var responsearray = [] 
        
    axios.get('https://myapi.net/api/role/allroles?pageSize=1000').then(function (response) {
    
        for(var i = 0; i < response.data.roles.length; i++)
        {
            var entry = response.data.roles[i];
            var entryid = entry.id;
    
            //pushing the promise into responsearray
            responsearray.push(axios.get('https://myapi.net/api/role/score/' + entryid).then(function (response2) {
                  console.log(i + " resolved");
            }).catch(function (error) {
        // handle error
        console.log(error);
    });
        })
        console.log("Done pushing all the promises");
        return responsearray;
    
    }).catch(function (error) {
        // handle error
        console.log(error);
    }).then(function (responsearray) {
        console.log("outer axios is resolved");
        // responsearray should have all the promises by now
        Promise.all(responsearray).then((results) => {
           console.log(results);
        }).catch(function (error) {
        // handle error
        console.log(error);
    });
    });