jj008
jj008

Reputation: 1093

Sequentially Loop through Array

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

Answers (1)

Amadan
Amadan

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

Related Questions