Chaining queries has unexpected UX

I have a retool app with a table and option-selector.

The option selector queries an api to populate the options, and when an option is chosen, I would like to use the value of that option to automatically trigger re-populating the table. I can make this interaction work fine (the table reloads when you select an option by using an event-handler).

The table data comes from

  • querying one API endpoint using the value of the option to get a list of ids (query1)
  • using this list of ids to query another API endpoint (query2)

The way I have achieved this is by having the table data be populated by a JS script. The JS script looks like:

var ids = await query1.data.ids;
if ((ids == null) |  (ids.length==0)){
  ids= [0]
}
var table_data = await query2.trigger({additionalScope: {id:ids}});

return await table_data

When I select an option in the table, I'm finding the UX to be inconsistent in what is returned - it appears as though query2 does not always run with the current result of query1 (ie query1 result using the current selection of option).

I have tried using Promise chaining more directly with .then syntax, however I see the same behaviour.

I'm not experienced with Javascript, so maybe I'm missing somethign very obvious or straightforward, but I can't figure out how to get my table to be populated correctly consistently - help and advice appreciated!

As I see it, you use ids as an argument but you don’t wait intill it’s resolved. Hence getting different results.

Try to return ids in the first promise. And use it in “then()”:


let promise = new Promise(query1.trigger());

promise.then(function(result) {
// get ids from result
  return Promise(query2 trigger with scope ids);
});

 return promise;

I’m on my :iphone: so I can’t type it out and test. But you can’t take ids out of the promise. Because when you trigger query2 in your example… ids is still [0]. Perhaps sometimes it will have ids and sometimes it will not when it performs query2.

It should be chained I think.. since query2 shouldn’t run without ids from query1 unless query1 returns zero ids right? So only when the results of query1 are in, then you should run query2.

After asking chatgpt for some help debugging this - the above solution almost works, but needs to be updated to be:

var promise = new Promise(function(resolve, reject) {
  query1.trigger().then(function(result) {
    var ids = result.ids;
    if (ids == null || ids.length == 0) {
      ids = [0];
    }
    resolve(query2.trigger({ additionalScope: { id: ids } }));
  }).catch(function(error) {
    reject(error); // Reject the promise in case of an error
  });
});

return promise;

Many thanks for the speedy response, very happy to see it all working now!

1 Like

yea that's it. I use chat GPT too. It's a great tool for learning. You can also ask it to add comments to the code so you can read it back later :wink: