Use Axios .then() with for loop index variable

Viewed 47

I want to iterate some page URLs, stored in an array, and retrieve them to do an operation over their html file. Since I need to store a result from said operation for each page to use them the next time I call the function, I want to pass the index (i) in the onResponse call so that it can assign the result to its proper place in the array. But instead of using the i value from the respective i-th iteration, this function call uses pages.length (i's last value). I know why this happens, but I don't know what would be a good solution. Any help here?

async function checkPages(){
const dateObj = new Date();
console.log(pages.length)
console.log(`Time: ${dateObj.toTimeString()}\n`);
for (var i = 0; i < pages.length; i++){
    axios.get(pages[i], { httpsAgent })
      .then(response => onResponse(response, i)
    )
      .catch(function (error) {
        onError(error)
      });
}
2 Answers

try using let instead of var

for (let i = 0; i < pages.length; i++) {

let are block scoped and var are function scoped.

Since you are calling an async method, using var it will finish the for loop and pass the last value to the callback. But using let it will keep the variable assigned in the block scope in the callback.

Here is the definition for let, and here is for var.

axios.get is a promise so your foreach is kicking off all http requests and i gets to the array length before you get any response from your API.

Try:

async function checkPages() {
  const results = await Promise.all(
    pages.map((page) =>
      axios.get(page, { httpsAgent }).catch((error) => {
        onError(error);
      })
    )
  );
  results.forEach((response, i) => {
    onResponse(response, i);
  });
}
Related