Timing issues after insert

I’m seeing intermittent timing issues in a Retool Mobile app where a query successfully inserts a row, but the .trigger() result is occasionally not available quickly enough on mobile.

Flow:

  • Button click runs insertVisitReport.trigger()
  • SQL inserts a row and returns it with OUTPUT inserted.*
  • On desktop preview, the inserted row is reliably available
  • On mobile, the record is created in the DB, but the JS sometimes does not receive the inserted row quickly enough
  • I added onSuccess, a short wait, and a fallback fetch query, but it still occasionally fails

Current pattern:

let insertedReport = null;

await insertVisitReport.trigger({
  onSuccess: (data) => {
    insertedReport = formatDataAsArray(data || [])[0] || null;
  }
});

let report = insertedReport;

if (!report?.VisitReportID) {
  await new Promise(resolve => setTimeout(resolve, 500));
  const fetchResult = await getVisitReportForTask.trigger();
  report = formatDataAsArray(fetchResult || getVisitReportForTask.data || [])[0] || null;
}

Question:

Is there a recommended Retool Mobile-safe pattern for waiting on a query result after trigger() when the DB insert itself succeeds, but the returned data is intermittently unavailable in the mobile runtime?

Should I avoid relying on the returned insert payload and always do a separate fetch after insert, or is there a better approach?

Hi @Shawn_Optipath

If you assign the result of the await/trigger to a variable, this should work reliably and that variable will contain the data as expected.

E.g.

  const data = await insertVisitReport.trigger();
  const report = formatDataAsArray(data || [])[0] || null;

  if (!report?.VisitReportID) {
    throw new Error("Insert query did not return the row.");
  }

  return report;

Thanks

Thanks @Jon_Steele,

In the end, we moved away from relying on a separate variable being populated later and instead captured the result from the awaited trigger directly into a local variable before continuing.

For anyone who finds this later, the pattern that ended up being reliable for us in Retool Mobile was:

let submittedReport = null;

await submitVisitReport.trigger({
  onSuccess: (data) => {
    submittedReport = formatDataAsArray(data || [])[0] || null;
  }
});

// continue processing using submittedReport

We then build our local object from that returned row and proceed with the remaining workflow steps.

After switching to this pattern, we haven't been able to reproduce the intermittent issue where the insert succeeded but the returned row wasn't available when the next lines executed.

So it looks like the important part was exactly what you suggested: assign the awaited trigger result to a variable within the trigger lifecycle and use that value rather than depending on a separately populated state value.

Thanks for the help