1

I'm trying to loop through an array and push the results to an array but the array returns as empty

const actionOpportunities = result.data.opportunities
const actionArray = []


for (let opportunities of actionOpportunities){
  const currentIDs = opportunities.id
  axios.get('apiURL.com='+currentIDs,clientGet)
  .then((results)=>{
    const actionsResult = results.data.actions

    actionArray.push(actionsResult)
  })
}

console.log(actionArray)
Capwiz
  • 61
  • 1
  • 11
  • Are you sure that `results.data.actions` is defined? What happens when you console log out `results.data`? Also, you should `console.log` after you push (while still in the for loop) – Rastalamm Aug 21 '19 at 19:37
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – thmsdnnr Aug 21 '19 at 19:40

3 Answers3

2

It's because actionArray.push will be execute later. Axios return a promise, and the then callback that you pass to push data to actionArray is executed after that console.log(actionArray).

To solve it: wait for all those promise to resolve, you can use Promise.all, and at that point you can collect all the results.

Something along the lines of:

const promises = []
for (let opportunities of actionOpportunities){
  const currentIDs = opportunities.id
  promises.push(axios.get('apiURL.com='+currentIDs, clientGet))
}

Promise.all(promises).then(allResults => {
  console.log(allResults)
}) 
Federkun
  • 36,084
  • 8
  • 78
  • 90
2

Try with async/await:

const actionOpportunities = result.data.opportunities
const actionArray = []

(async () => {
  for (let opportunities of actionOpportunities){
    const currentIDs = opportunities.id
    const res = await axios.get('apiURL.com='+currentIDs,clientGet)

    actionArray.push(res.data.actions);
  }

  console.log(actionArray);
)();

Or if you don't want to call the requests one at a time:

const actionOpportunities = result.data.opportunities
const promises = []

for (let opportunities of actionOpportunities){
  const currentIDs = opportunities.id
  const promise = axios.get('apiURL.com='+currentIDs,clientGet)
    .then(res => res.data.actions);
  promises.push(promise);
}

Promise.all(promises).then(results => {
  console.log(results);
});
Maxim Pyshko
  • 551
  • 4
  • 14
1

This looks like a timing issue, the console.log(); is being run before the logic inside the .then(). Hence looking like the data has not been pushed. Try the following.

.then((results) => {
    const actionsResult = results.data.actions
    actionArray.push(actionsResult);

    console.log(actionArray); // should be defined here.
});
devDan
  • 5,969
  • 3
  • 21
  • 40
  • This allowed me to log the actionArray, but how would I add the completed array into res.render further down the page? – Capwiz Aug 21 '19 at 19:41
  • 1
    I cant see further down the page unfortunately, but hopefully this has answered the question you posted :) – devDan Aug 21 '19 at 19:42
  • const actionOpportunities = result.data.opportunities const actionArray = [] for (let opportunities of actionOpportunities){ const currentIDs = opportunities.id axios.get('apiURL.com='+currentIDs,clientGet) .then((results)=>{ const actionsResult = results.data.actions actionArray.push(actionsResult) console.log(actionArray) }) } res.render('index', { renderActions : actionArray }) – Capwiz Aug 21 '19 at 19:45
  • 1
    Sorry I have helped with the bit that made sense to me, Im yet to know the ins and outs of express. Maybe check https://expressjs.com/en/api.html#res.render – devDan Aug 21 '19 at 19:47