Reputation: 1093
I'm trying to loop through an array and then push items of that array to a variable/object (tempComponents
). Then reorder tempComponents
before executing storeNewComponents
. As I loop through the array, I'm making API calls to get the response to push to tempComponents
.
My approach here is that when the loop reaches the end (i = array["steps"].length
), it'll execute storeNewComponents
. But when I run the loop, it doesn't go through the array in order so storeNewComponents
doesn't gets executed at the end (and the order of going through the array is different every time).
Why is that and how can I make sure the loop goes through the array sequentially?
array: {
steps: [a, b, c, d]
}
tempComponents: {
components_under_section: []
}
loopReorderStore(){
for (let i = 0; i < array["steps"].length; i++){
this.generateBlankComponent({
componentType: 'Composition',
options: {
title: array["steps"][i],
content: "sample sample"
}
})
.then( (componentData) => {
let componentPath = "/projects/" + this.currentLessonId + "/components"
this.apiPost({ path: componentPath, data: {"component": componentData} })
.then( (componentResponse) => {
console.log("componentResponse: " + JSON.stringify(componentResponse))
// add to tempComponents
this.tempComponents.components_under_section.push(componentResponse.data)
console.log("tempComponents after creating component: " + JSON.stringify(this.tempComponents))
// reorder tempComponents
this.reorderComponents(this.tempComponents)
console.log("tempComponents after reordering: " + JSON.stringify(this.tempComponents))
if (i === (array["steps"].length - 1)) {
this.storeNewComponent(this.tempComponents)
}
})
})
}
}
Upvotes: 0
Views: 265
Reputation: 198566
You want to launch an asynchronous API call for each element, then when ALL of them are finished, launch this.storeNewComponent
. To do this, collect the promises you create in the loop, and then use Promise.all(promises).then(...)
to launch your finisher.
let promises = array.steps.map(step =>
return this.generateBlankComponent(...) // return a promise to `promises`
.then(componentData => {
...
return this.apiPost(...) // return a promise to allow chaining
.then(componentResponse => {
...
return tempComponent; // return the value itself
});
});
});
Promise.all(promises) // wait on each promise, and its chain
.then(tempComponents => { // and get the array of results that parallels
this.storeNewComponent(tempComponents); // the original array of inputs
});
(Be sure not to forget all the return
statements I added, which are critical to ensure that the correct values dribble down to the aftermath of Promise.all
.)
Upvotes: 1