Issues with await and an SQL-Query

Hi there,

I do have the following issue:
I want to use await for a query to return before working with the data but obviously await does not wait for the data to be returned before continuing the processing.

Please consider the following (simplified to the essential) source-code, triggering an SQL-Query and just returning the number of names in the result:

// get all accounts with group-information
await awaitTestSQL.trigger();

// logging
console.log('#K-Gesamt: ' + awaitTestSQL.data.name.length);

The Resource-Query with the name awaitTestSQL is an SQL-Statement in SQL-Mode and is as simple as:

select * from account

Executing this simple script delivers the following result:


In the first run (in the blue box) the SQL-statement is executed successfully but the data is NULL!? :thinking:
Re-executing the script without changing any data in the database or anything else, delivers the results in the orange box.

For me it seems like await does not wait for the query being executed and the results being returned but immediately continues with the execution - that's why there is an error in the first run. In the 2nd run I guess it takes the cached results from the 1st run.

My question: what do I need to change in the script above to really make the execution wait, until the result of awaitTestSQL are returned?

Thanks a lot in advance for any hint!

Hi @Markus,

Try this:

const result = await awaitTestSQL.trigger()

console.log('#K=Gesamt: ', result.data.name.length)

This is capturing the result in the result variable.

Hi @MikeCB,

thanks for the hint, but I'm afraid the result is even worse - I do neither get a result in the 1st nor in the 2nd run:
awaitIssue2

Sorry, maybe I should have asked more questions! Where are you running this code from? Are you in an app or a workflow? A code block, query, transformer etc?

@MikeCB: I have to apologize, as I was not precise enough... sorry! :see_no_evil:
The code is within a JS-Query and called from an app.

Finally the JS-Query should be triggered by the Change-Event of a Multi-Select-Box but for testing purposes (as I was experiencing the issue described) I simply executed the JS-Query by clicking the "Run"-Button in the Resouce-Editor.

However - the result is the same if I execute it "manually" by clicking it or letting it be triggered by the event.

Hi @Markus,

That's very strange! Are you sure your awaitTestSQL is returning data? You don't have a transformer or something in there? I just tried to basically replicate what you've got.

I have query6, a resource query:
image

Then I have query7, a JS Query:
image

Then I have a multi-select listbox with a changeHandler event that looks like this:
image

And the result after changing the multi-select box or manually running query7 looks like this:
image

Is there anything in there that doesn't match what you've done?

Hi @MikeCB,

first of all thank you for taking a look into that so thoroughly.
I went through the steps you posted - the results:

  1. please see my resource query - as far as I can see the only difference is, that I am using PostgreSQL and not Retool database - as you can see from the screenshot, there are no transformers or anything else manipulating the data returned from the query:

  2. executing the query in retool manually returns several lines of data (the first two lines are visible in the screenshot as well)

  3. I removed my change handler for the time being to narrow down the issue and execute the JS Query directly - my assumption is that the changeHandler won't work better than the query that is called by it :wink: So when talking about differences, this would be different.

  4. I adapted my code to your setup (although this should not make any difference) and replaced the data to be logged to the whole data and not a detail out of it.
    code
    This naturally results in a success in the execution of the query but as you can see in the logging, in the first run the return is still empty...
    exec_result

My conclusion would be: is there anything special with the execution of PostgreSQL-queries that prevents Javascript from executing the await command properly? :thinking:
If the answer is yes - how can I workaround that?

Thanks a lot for any thoughts in advance,
Markus

@MikeCB , may I ask you to adapt your source-code in a way that the result of the query is reset for sure before execution:

// make sure data is empty
query6.data = null;

// execute and (hopefully) wait for the query
await query6.trigger();

// log to the result to the console
console.log(query6.data);

Doing this, do you still get a result?

In my case, I don't get any result what makes me believe, that await does not wait for the call being executed. This would be in line with the result to your suggestion from Post #2 where you suggested I should put the result of the query directly to a variable and testing it turned out it was empty all the time.

There is another indication I found, but I'm not sure if this interpretation is valid - in the debug window, I have the impression, the execution of the Javascript starts earlier (what would be fine and logical) but both terminate at the same time (what looks unusual to me, as the result of the query still needs to be logged to the console by the JS!?).

Could you please check if this is the same with your script as well?
Thanks a lot in advance,
Markus

Hi @Markus,

Very strange! I was able to reproduce your experience when I set query6.data = null.

I then tried modifying the JS code to this:

let result = null
const fn = async () => {
  query6.data = null
  const data = await query6.trigger()
  return data
}
result = await fn()
console.log(result)

For what it's worth, the Retool DB is also a Postgres db. I'm also seeing similar thing in the timeline view. Some kind of race condition maybe? Maybe the way Retool encapsulates the JS Query's? :man_shrugging: But give the code above a shot and see if it at least works for your use case.

1 Like

Hi @MikeCB,

I worked on it in parallel and just saw your posting - both of us came more or less to the same solution. Just if somebody comes over this thread with a similar issue, the solution I came up is

// reset data
awaitTestSQL.data = null;

// wait for the query to be executed and set the data attribute to the result returned
awaitTestSQL.data = await new Promise(resolve => {
  resolve(awaitTestSQL.trigger());
});

// logging
console.log('#K-Gesamt: ' + awaitTestSQL.data.name.length);

what is a very similar solution you suggested, just in different writing.
Thank you very much for your help! :hugs:

The result is now as expected:
SuccessRetool

Regards, Markus

2 Likes