Running script on app load variable initial values not set yet

I have a script that runs on page load and compares a url parameter to an app variable, which is only being set once via the initial value property. But at run time of the script the variable is undefined. It only works if i set the delay time of the script to start, but it's blocking the initial page render and causes unnecessary flickering.

Is there a better way to run a script only after a variable, or set of variables initial values have been set?

We encountered flickering issues in our large customer-facing app, but I recently resolved them by implementing a "Loading" screen. Here's what I did: I started by hiding all components by default and created a full-screen modal that is visible by default. I also implemented a js function that I named "initialize." I then placed all my on-page load queries to trigger within this function and ran them in the required order. This way, I only have one query that needs to run on page load, and I can control the loading order as needed.

To make the loading experience a little more enjoyable, I added a progress circle on the loading screen that auto-increments every 100 milliseconds. It typically takes about 10 seconds to load, but you can reduce this time by half if desired and still get the same effect, any faster and it gets a little wonky. Once your page load queries finish, you can set all the component's hidden values to false and the modal's hidden value to true, resulting in a clean and polished appearance. I also recently added some text that says "Loading" initially but randomly changes every 20% based on an array of loading "Sayings". Made it a little more fun.

2 Likes

Hello @Dev ,

Currently, there isn't an in-built feature in Retool to guarantee your script runs only after all initial values have been set. This being the case, a common workaround is to utilize JavaScript's setTimeout or setInterval function. This delays the execution of your script until all the necessary values are initialized.

Alternatively, one useful technique could be to structure your code such that the script runs only when all necessary dependencies are defined. In cases where your script is dependent on the result of a query, you may move your script into the .then() section of the query. This step ensures the script will only run post the success of a query.

You may also consider using variables' .value (Promise) instead of .data. The .value will return a Promise that resolves when the initial value has been set. For instance:

let variableValue = await variable.value;
// rest of your script

This technique assures your script will only execute when the variable(s) has been initialized, mitigating the need for unnecessary delays and flickering.

In the case if a variable isn't defined in your script, setTimeout can be used to recursively call the function again after a short pause.

Please note, depending on the specifics of your application and its set up, the best solution may vary. Always be cautious while using localStorage, which comes with its own set of challenges including avoiding query loops and assuming apps are open in different tabs.

The team at Retool is looking to add a feature that would allow proper order of script execution in future.

-Brett