Check for updated Value after Trigger

Hello all,

for a note, I am using the Retool database.

I am trying to get it so the JS script keeps waiting for a new value before proceeding. The below is what I currently have.

When I used a longer await 1 time (~10,000 ms) it updated with the correct new record id. However, to ensure the record is accurate, I want to run a loop until the new record comes through, just in case the database takes longer than 10,000 MS to update.

The below is what I have right now that just loops infinitely despite the database being updated in another tab.

var oldRecord = parseInt(newestRecord.data.id[0])

var newRecord = parseInt(oldRecord)
console.log("old Record " + oldRecord)
console.log("new Record " + newRecord)

while (oldRecord = newRecord) {
  await new Promise(resolve => setTimeout(resolve, 1000));
  Promise.all(newestRecord.trigger());
  newRecord = newestRecord.data.id[0]
  console.log("old Record " + oldRecord)
  console.log("new Record " + newRecord)
}

console.log(newestRecord.data.id[0])```

I am still getting an error with getting the updated values even with adding a 15 second delay to trigger the next query to get the updated information.

Caching is turned off for all queries. However, this seems like a cache issue.

Bump

Bump

Hi! I'm a little confused by your script.

var oldRecord = parseInt(newestRecord.data.id[0])

var newRecord = parseInt(oldRecord)

...

while (oldRecord = newRecord)

These values will always be the same as they both refer to the same ID. You're also using = which is an assignment operator. To check equality you need == or ===.

It seems like you want something like:

var oldID = parseInt(newestRecord.data.id[0])

var newRecord = await rewestRecord.trigger()
var newID = newRecord.id[0]

if (oldID === newID) {
// do something
}else{
// do something else
}

// maybe return a value here?

Hi @kschirrmacher,

Oops! I did mess up that equality. However, even when corrected, I am still running into the same issue. I have tried updating the code to the following but still with no luck. Oddly enough, it does give the right id when the JS query ends and next query after a success is triggered:

async function waitForNewRecordUpdate() {
  const oldRecord = parseInt(newestRecord.data.id[0]);
  let newRecord = oldRecord;

  // Keep looping until oldRecord is different from newRecord
  while (oldRecord === newRecord) {
    // Delay the execution by 1 second
    await new Promise(resolve => setTimeout(resolve, 1000));
    
    // Trigger the update
    await new Promise.all(newestRecord.trigger());
    
    // Update newRecord with the new value
    newRecord = parseInt(newestRecord.data.id[0]);
    
    // Log the updated values
    console.log("old Record " + oldRecord);
    console.log("new Record " + newRecord);
  }
}

Hey there,

It looks like you're still running into a quirk of the React framework that Retool is built on.

await new Promise.all(newestRecord.trigger());
    
    // Update newRecord with the new value
    newRecord = parseInt(newestRecord.data.id[0]);

While await will tell your code to pause execution until newestRecord.trigger() resolves, it won't pause execution while newestRecord.data is updated. This is because data is a React state object, which may be updated in batches on a delayed basis behind the scenes to improve performance. You can read a bit about it here: https://legacy.reactjs.org/docs/react-component.html#setstate

Here's what is happening in the code now:

async function waitForNewRecordUpdate() {
  const oldRecord = parseInt(newestRecord.data.id[0]); //Let's say this returns 1
  let newRecord = oldRecord; //This becomes 1=1

  // Keep looping until oldRecord is different from newRecord
  while (oldRecord === newRecord) { // 1 is === to 1
    // Delay the execution by 1 second
    await new Promise(resolve => setTimeout(resolve, 1000));
    
    // Trigger the update 
    await new Promise.all(newestRecord.trigger()); 
   // The query runs and let's say it returns 2. Code execution resumes
    
    // Update newRecord with the new value
    newRecord = parseInt(newestRecord.data.id[0]); 
   // In the background, Retool's code has queued a state update for the value that the query returned, 2. However when this code runs, the value of data.id[0] is still 1. newRecord remains 1.
    
    // Log the updated values
    console.log("old Record " + oldRecord); // Still 1
    console.log("new Record " + newRecord); // Also still 1, but freshly assigned
  }
}

I still recommend assigning the result of the query to a variable (which doesn't have a delay like a React state does) and using that in your function, rather than relying on the query's data object.

async function waitForNewRecordUpdate() {
  const oldRecord = parseInt(newestRecord.data.id[0]);
  
  let newRecord = oldRecord;

  // Keep looping until oldRecord is different from newRecord
  while (oldRecord === newRecord) {
    
    // Trigger the update
    const newRecordQuery = await newestRecord.trigger();
    
    // Update newRecord with the new value
    newRecord = newRecordQuery.id[0]
    
    // Log the updated values
    console.log("old Record " + oldRecord);
    console.log("new Record " + newRecord);
  }
}
1 Like