0

I'm tying to process logic in nested ForEach Loops and when completed set a loading flag to false. however the this.isLoading = false; code is being hit before the For Loops complete.

I wondered if there is a flag/way to determine that the forEach loops have completed?

Thanks in advance for your help. You'll note the "Reaching here before loops completed." comment in the following code. I would like this only to fire when the forEach logic has actually completed.

    @wire(getProgrammesList, { contactId: "$recordId" })
    wiredProgrammesList({ error, data }) {
      this.isLoading = true;
      if (data) {       
          (Object.keys(this.programmeList)).forEach((progIdKey) => {
            let programmesForChannel = this.programmeList)[progIdKey];

            Object.entries(programmesForChannel).forEach(([key]) => {
                console.log('Hello from here ' + key);
                let myObj = this.checkAndApplyStatusForProgrammes(programmesForChannel[key]);
                this.programmesByChannelByStatus[programmesForChannel[key].Channel_Code__c] = myObj;
            });
        });
        this.isLoading = false;  // Reaching here before loops completed.
      } else if (error) {
        console.log('AN ERROR occurred ' + this.error);
        this.error = error;
        this.programmesByChannelByStatus = {};
        this.isLoading = false;
      }
0

2 Answers 2

0

The issue you're encountering is due to the asynchronous nature of JavaScript. The forEach method is synchronous, but its callback functions might include asynchronous operations that prevent the isLoading flag from being set correctly.

Here is the code example:

  if (data) {
    let allPromises = [];

    Object.keys(this.programmeList).forEach((progIdKey) => {
      let programmesForChannel = this.programmeList[progIdKey];

      Object.entries(programmesForChannel).forEach(([key]) => {
        console.log('Hello from here ' + key);
        
        let promise = new Promise((resolve) => {
          let myObj = this.checkAndApplyStatusForProgrammes(programmesForChannel[key]);
          this.programmesByChannelByStatus[programmesForChannel[key].Channel_Code__c] = myObj;
          resolve();
        });

        allPromises.push(promise);
      });
    });

    Promise.all(allPromises)
      .then(() => {
        this.isLoading = false; // Will only reach here when all loops have completed
      });
  }
0

On finding & generally the following it has helped me to achieve what I've needed. https://community.appsmith.com/content/guide/how-correctly-execute-loop-synchronously-javascript

1
  • Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
    – identigral
    Commented Jul 3 at 18:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .