0

I'm working with an async function to try and pull data into an Array with Axios. When I log the data inside the forEach below, it shows up, but when I log it outside the forEach, it returns blank. I assume this is because the program is still running, but I'm not sure how to solve without a timeout.

const user = async(IDs) => {

    var output;
    var URL;
    var result = [];

    IDs[0].forEach(async(id) => {
        URL = "https://example-api.com/" + id;
        output = await axios.get(URL)
            .then(function(data){
                result.push(data.data.text);
                console.log(result) // Returns the data
            });
    })

    console.log(result) // returns blank

}
lernbr
  • 441
  • 2
  • 6
  • 13
  • use for of instead of forEach – Parse Shyam Jun 26 '20 at 12:18
  • It's simply not working because you're calling an async function inside foreach loop.. to make it work just add `await` just before your `IDs[0].foreach` line and everything will work – Shubham Jun 26 '20 at 12:25
  • there are multiple mistakes like using `asycn` on a forEach loop. Then you use `.then()` with `await` that also dont really make sense – bill.gates Jun 26 '20 at 12:36
  • Also relevant: [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/q/23667086) – VLAZ Jun 26 '20 at 13:51

4 Answers4

3

All other solutions are good but they are fetching data one by one and this makes your code a little slower.

Use this approach as it'll take full advantage of event-loop and this will execute your program much faster.

const result = await Promise.all(IDs[0].map(id => {
  return axios.get(`https://example-api.com/${id}`)
    .then(data => (data.data.text)) 
}))
megi
  • 27
  • 5
Shubham
  • 756
  • 4
  • 13
0
   const user = async(IDs) => {
    var output;
    var URL;
    var result = [];

    for (const id of IDs[0]) {
        URL = "https://example-api.com/" + id;
        try {
            output = await axios.get(URL);
            result.push(data.data.text);
        } catch (error) {
            console.log(error)
        }
    }
}

Give it a try

Parse Shyam
  • 366
  • 2
  • 14
0

@Shubham has proposed the most efficient solution (Promise.all and Array.map), however, combining async / await with Promise.then can kill readability, especially as complexity increases.

Where possible, await should be preferred to Promise.then:

const result = await Promise.all(IDs[0].map(async id => {
    const data = await axios.get(`https://example-api.com/${id}`);
    return data.data.text;
}));
Johnathan Barclay
  • 18,599
  • 1
  • 22
  • 35
-1

Async function inside a foreach loop doesnt wait for the axios response.

Try using for-in loop.

for (const id of IDs[0]) {
    URL = "https://example-api.com/" + id;
    const output = await axios.get(URL)
    result.push(output.data.text);
    console.log(result) // Returns the data       
})
Dhruv Shah
  • 1,611
  • 1
  • 8
  • 22
  • Also you should not require the `then` statement. The await operation directly returns the response of the asynchronous operation to the assigned variable. – Dhruv Shah Jun 26 '20 at 12:21