2

I'm attempting to use async/await with axios.then() within a for of loop. The function fails to run or even attempt the axios call. I have a feeling using the then() function is part of the problem.

I need the for loop to wait until the then() function has run before continuing on to the next array item. Any ideas how I can alter my code to get the axios.then() functions to run asynchronously?

accounts = [{a},{b},{c}, ...] // Example of accounts array

async function get_user_data (accounts) {
  // For of loop
  for (let [index, user] of accounts.entries()) {
    // Currently using await before axios call
    await axios.get(url, headers)
      .then(function(data) {
        console.log(data)
      })
      .catch(function(error) {
        console.log(error)
      })
  }
}

UPDATE:

Issue was ultimately being caused by the Vue frontend compiling my application. Resolved by following the stack overflow solution posted here. Note, that the code now functions as expected. The solution offered by Dacre Denny helped me decide the issue must be located somewhere else as his should have worked but did not until the problem with Vue was solved. Takeaways:

  1. Use simple tests to confirm issue not with code
  2. Check webpack, babel, and other compiler configs if above doesn't work
Jason
  • 555
  • 6
  • 14
  • I don't think sending http request inside for loop is a good idea. – Christhofer Natalius Jun 25 '19 at 03:00
  • Possible duplicate of [What's wrong with awaiting a promise chain?](https://stackoverflow.com/questions/54385676/whats-wrong-with-awaiting-a-promise-chain) – dwjohnston Jun 25 '19 at 03:24
  • This `for` loop will already wait for the `.then()` to run before continuing. If you think it isn't, then it's probably because whatever asynchronous stuff you're doing inside the `.then()` handler isn't returning a promise so it can link into the chain. Show us your code for what's inside the `.then()` handler and we can more likely help you. – jfriend00 Jun 25 '19 at 03:33
  • FYI, you don't put answers into your question here. You put answers in answers and questions in questions. So, since you've already posted your own answer (which is allowed here), then you should remove the answer stuff from the question. It doesn't belong there. After some time passes, you can "accept" your answer too. – jfriend00 Jun 25 '19 at 03:45
  • 1
    Given that the issue isn't in the question, the issue–causing agent (Vue.js) isn't tagged and the solution is in another post, either update the title and mark this question as a duplicate, or delete it. – RobG Jun 25 '19 at 04:15

3 Answers3

2

In general, it is considered an anti-pattern to mix the promise interface (ie .then()) with await/async semantics.

Seeing that the get_user_data function is defined async, consider a revised implementation based on a try/catch block for clearer program flow and greater predictability in the asynchronous behaviour of your loop:

async function get_user_data (accounts) {
  for (let [index, user] of accounts.entries()) {

    /* try/catch block allows async errors/exceptions to be caught
    without then need for a .catch() handler */
    try {    

        /* Using await, the response data can be obtained in this 
        way without the need for a .then() handler */
        const data = await axios.get(url, headers)
        console.log(data);
    }
    catch(error) {

        /* If an error occurs in the async axios request an exception
        is thrown and can be caught/handled here */
        console.log(error)
    }
  }
}
Dacre Denny
  • 29,664
  • 5
  • 45
  • 65
  • 2
    This doesn't, by itself, solve whatever problem the OP had because the OP's code already was waiting for the `.then()` handler to run. One can argue about the "style" of using `await` and `.then()`, but that isn't causing whatever problem the OP has. – jfriend00 Jun 25 '19 at 03:35
0

Thanks to Dacre Denny for the quick help. His test code helped me determine the problem was not with the code.

The Issue was ultimately being caused by the Vue frontend compiling my application which does not at this date support async/await out of the box. Resolved by following the stack overflow solution posted here. Note, that the code now functions as expected. Takeways:

  1. Use simple tests to confirm issue not with code
  2. Check webpack, babel, or other compiler configs if above doesn't work
  3. A lack of errors when function fails to run may indicate a compilation error. Check configs.
Jason
  • 555
  • 6
  • 14
0
  async get_user_data(accounts) {
        // For of loop
        (async() => {
            for (let [index, user] of accounts.entries()) {
                // Currently using await before axios call
                await axios.get(url, headers)
                    .then(function(data) {
                        console.log(data)
                    })
                    .catch(function(error) {
                        console.log(error)
                    })
            }
        })();
    },