I’m having an issue where localStorage.setValue() doesn’t seem to persist before navigating to another page, causing missing values on the redirected page.
I want to store company_id, displayName, and email in localStorage after login, ensure they are fully set, and only then redirect to the employees page. The expected behavior is that all values should be available immediately upon landing on the employees page.
Steps Taken So Far
- After a successful login, I fetch user details using a query (getUserData).
- I store these values in localStorage:
await localStorage.setValue("company_id", getUserData.data[0].company_id);
await localStorage.setValue("email", getUserData.data[0].email);
-
I then use utils.openPage("employees") to navigate to the employees page.
-
However, on the employees page, localStorage.values.company_id is sometimes missing, causing an empty state.
-
I tried adding await new Promise(resolve => setTimeout(resolve, 500)); before redirecting, but it still happens.
-
I also attempted a while loop to check if company_id is set before redirecting, but the page still loads before the value appears.
How can I ensure localStorage is fully set before redirecting to prevent missing values on the next page? Is there a better approach to handling this in Retool?
Appreciate any help! 
1 Like
Hey @Tom_Suter,
Welcome to the forum!
The approach I would take is to create a success event handler in your getUserData query, set a runScript event with the localStorage and utils.openPage methods, and I would add adebounce to the event to make sure the query fully loads the data before the script runs.
For safety I would also add a timeout between the localStorage setValue and the utils.openPage.
Apologies if this is what you're already doing, but I doesn't seem clear to me where you're adding the script.
1 Like
Hi @MiguelOrtiz , thanks for your reaction.
What happens is the following after submitting the form:

firebaseLogin does a succesful REST API call and then runs this script on success:
await authToken.setValue(firebaseLogin.data.idToken);
await localStorage.setValue("firebaseId", firebaseLogin.data.localId);
await localStorage.setValue("authToken", firebaseLogin.data.idToken);
It also runs getUserData (should be after succesful firebaseLogin, but I'm not sure if all event handlers are triggered at the same time or after each other (top to bottom)).
getUserData runs a firebase query to get the user data.
Once that's succesful done it runs the following script:
await localStorage.setValue("displayName", getUserData.data[0].displayName);
await localStorage.setValue("company_id", getUserData.data[0].company_id);
await localStorage.setValue("email", getUserData.data[0].email);
// Ensure `company_id` is fully stored before redirecting
let maxRetries = 100; // Retry up to 4 seconds
let retryCount = 0;
while (!localStorage.values.company_id && retryCount < maxRetries) {
console.log(`Waiting for company_id... Attempt ${retryCount + 1}`);
await new Promise(resolve => setTimeout(resolve, 200)); // Delay 200ms
retryCount++;
}
// Double-check before redirecting
if (localStorage.values.company_id) {
console.log("✅ company_id stored, redirecting now:", localStorage.values.company_id);
utils.openPage("employees");
} else {
console.error("❌ company_id was NOT set after retries. Stopping redirect.");
}
As you can see I tried to slow it down already a littlebit.
Only when this all is successfully done it should redirect to the employees page (see last part of last script above).
For some reason it can already jump to this page, while it hasn't queried the data yet. How can I avoid this? Thanks for any help.
Hey @Tom_Suter,
So the first thing that pops to the eye is that you also have getUserData.trigger() as an evnet handler in your form, but from what I see you should remove that and add this as a success event on firebaseLogin.
await authToken.setValue(firebaseLogin.data.idToken);
await localStorage.setValue("firebaseId", firebaseLogin.data.localId);
await localStorage.setValue("authToken", firebaseLogin.data.idToken);
await getUserData.trigger()
Maybe what you could do is create a success event handler within getUsarData that has
await localStorage.setValue("displayName", getUserData.data[0].displayName);
await localStorage.setValue("company_id", getUserData.data[0].company_id);
await localStorage.setValue("email", getUserData.data[0].email);
await query1.trigger()
With query1 being
// Ensure `company_id` is fully stored before redirecting
let maxRetries = 100; // Retry up to 4 seconds
let retryCount = 0;
while (!localStorage.values.company_id && retryCount < maxRetries) {
console.log(`Waiting for company_id... Attempt ${retryCount + 1}`);
await new Promise(resolve => setTimeout(resolve, 200)); // Delay 200ms
retryCount++;
}
// Double-check before redirecting
if (localStorage.values.company_id) {
console.log("✅ company_id stored, redirecting now:", localStorage.values.company_id);
utils.openPage("employees");
} else {
console.error("❌ company_id was NOT set after retries. Stopping redirect.");
}
Hope this makes sense!
2 Likes
Cool! I got it working like that.
getUserData is a little bit slow though, but I can fix that later. Most important is that it's reliable.
2 Likes