Module output not being updated in asynchronous while loop

Goal:
I'm trying to set up a Retool JS workflow that will onboard a lesson group with 1-4 students. To avoid having to manually duplicate student information fields, I want to store each student's info as an individual module that can add a student itself. Then, once each individual student module has completed, the parent app will then create the lesson group with all students' ids.

The problem is that, when I try to capture the output of the individual module, I'm getting conflicting values. The preview (hover over) function shows that the output value (outputStudentId) is indeed updating properly:

However, in the loop, it keeps saying that the value is null. This is contradictory, and causing the while loop condition to never be triggered.

Here is the console.log where I print out this value directly:

Steps:

I've tried:

  • Running the loop as a synchronous one, but this causes the Retool app to crash.
  • Checking my sister Onboard Staff app, where I did a similar thing with status checking and DID get it to work. I don't see why the output value is returning null this time around. Is it because there's a lot of relational dependencies or dependency cycles between modules?

Moving forward, if I can't get this to work, I'm going to try to use the Repeatable List View. However, it's taken me so much time to build the Modules, that I'd prefer to get it working.

App json export:
))

Hi @Jeffrey_Yu,

That is very odd that the IDE is able to show the correct outputstudentId of 29, while the loop says the value is null :face_with_monocle:

Can you share a full screenshot of the loop you are running? It is hard to tell what could be the culprit from the limited snippets.

Modules are known to be 'tricky' to work with but we are planning a major overhaul to release a version 2.0 of modules that will be greatly improved.

A repeatable list view might be the better option, if this is a module specific bug :sweat:

Yes, I ended up using a repeatable list view, which worked!

Here's the code though, so you can debug in the future.

async function addNewLessonGroupJS() {
  try {
    await isAnythingLoading.setValue(true);
    await onboarding.showNextView();

    let groupSize = select_group_size.value;
    
    /**
     * The `execute` variable is used to track the progress of the onboarding process.
     * - It starts at 0, indicating that execution has not yet started.
     * - It increments from 1 to `groupSize` as each student-parent pair completes onboarding.
     * - Once all are completed, `execute` is set to 5 to signal that the process is finished.
     */
    await execute.setValue(0); // Initialize execution tracker
    
    for (let i = 0; i < groupSize; i++) {
      await execute.setValue(i + 1);
      console.log(`execute set to ${i + 1}`);
      
      let secondsWaited = 0;
      let studentStatusesAll, parentStatusesAll;
      
      while (true) {
        // Refresh student and parent statuses dynamically
        studentStatusesAll = [
          student1.outputStudentId,
          student2.outputStudentId,
          student3.outputStudentId,
          student4.outputStudentId
        ];
        
        parentStatusesAll = [
          parent1.outputParentId,
          parent2.outputParentId,
          parent3.outputParentId,
          parent4.outputParentId
        ];

        let studentStatus = studentStatusesAll[i];
        let parentStatus = parentStatusesAll[i];
        
        console.log(`Waiting for student ${i + 1} and parent ${i + 1} to be ready... (${secondsWaited} seconds elapsed)`);
        console.log(`Current student status:`, student1.outputStudentId);
        console.log(`Current parent status:`, parent1.outputParentId);
        
        if (studentStatus !== null && studentStatus !== undefined &&
            parentStatus !== null && parentStatus !== undefined) {
          break;
        }
        
        await new Promise(resolve => setTimeout(resolve, 1000)); // Wait 1 second before checking again
        secondsWaited += 1;
      }

      console.log(`Student ${i + 1} and parent ${i + 1} are ready after ${secondsWaited} seconds.`);
    }

    await execute.setValue(5); // Indicate completion
    console.log("All students and parents are ready.");
   
  } catch (error) {
    console.error("An error occurred while triggering queries:", error);
  }
}

// Call the function to start the process
addNewLessonGroupJS();
1 Like

Amazing work!

Super impressive, great to hear you got things working as you had hoped. Apologies again for the modules!