0

Is it possible to interpolate values inside a for loop? I'm using axios and I want that, when it finishes a cycle, it gets to the next json file taking the next value of an array; These are my attempts (not working)

my first try was:

const axios = require('axios')
const array = [foo, bar, baz];
(async()=>{
    for(i=0;i<array.length;i++){
        const res = await axios.get(`https://blabla/${array[i]}.json`)
        // actions
    }
})()

but in this way axios makes requests interpolating only the last element of the array (in this case "baz"), while I want that it makes the first request with "foo"and then, when it has completed all the actions, it makes the second request to "bar" and so on up to "baz"

my second try was:

const axios = require('axios')
const array = [foo, bar, baz];

array.forEach(async function(item){
    const res = await axios.get(`https://blabla/${item}.json`)
    //actions
})

but with this code I get the error "TypeError: Cannot set property 'res' of undefined"

what can I do?

Drun
  • 529
  • 1
  • 7
  • 17

3 Answers3

1

Are you ABSOLUTELY SURE the first way you had it isn't working? Because it works for me. I made a toy example to show what would happen here:

var axios = {
  get: async function(url) {
    await new Promise(r => setTimeout(r, 150));
    console.log('axios url', url);
  }
}
var array = ['foo', 'bar', 'baz'];
(async()=>{
    for(i=0;i<array.length;i++){
        const res = await axios.get(`https://blabla/${array[i]}.json`)
        // actions
    }
})()

For me, it waits 150ms and logs 'foo', 'bar', then 'baz' urls

TKoL
  • 13,158
  • 3
  • 39
  • 73
1

Your code works. You should of course change for (i = 0 to for (let i = 0 but it doesn't affect the output. Look for an error in your array of api data. See my example with jsonplaceholder

const axios = require('axios')
const f = async () => {
  const array = ['1', '2', '3']
  for (let i = 0; i < array.length; i++) {
    const res = await axios.get(`https://jsonplaceholder.typicode.com/users/${array[i]}`)
    console.log(res.data.name)
  }
}
f()

Difference between your first and second example is that the first one will run requests sequentially, while the second one will run them in parallel. More idiomatic way to do this would be using Promise.all

const axios = require('axios')
const f = async () => {
  const array = ['1', '2', '3']
  const response = await Promise.all(array.map(i => axios.get(`https://jsonplaceholder.typicode.com/users/${i}`)))
  const data = response.map(item => item.data)
  console.log(data)
}
f()
Max
  • 4,473
  • 1
  • 16
  • 18
  • Yeah you're right, I misunderstood where the problem is in my code, it seems that it does actions just for the last url, thx btw – Drun Dec 31 '19 at 13:53
0

You can add let before i, it will make it locally visible and you will not get only last element

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

but better instead of await, which is blocking, use

Promise.all(
  array.map(v => axios.get(`https://blabla/${v}.json`))
).then(resp => resp.forEach(v => 
 //...some action with each result
))
Dmitry Reutov
  • 2,995
  • 1
  • 5
  • 20