Thanks for sharing your concern — I completely understand the issue you're facing.
In Retool, variables initialized using expressions that reference other components (like auditQuestions.ready_to_submit) can sometimes behave unexpectedly. This typically happens because those variables are evaluated before the referenced components (like queries or temporary states) are fully loaded or bound. As a result, the variable might end up with an incorrect or empty value.
Recommended Solutions
Option 1: Use a Transformer (Recommended)
Instead of relying on a variable, create a Transformer (click the "+" button → select Transformer) with the following logic:
return auditQuestions.ready_to_submit === false;
Then, in the Disabled property of your button, use:
{{ transformer1.value }}
This approach ensures the expression is evaluated after all components have loaded properly, giving you more reliable results.
Option 2: Use the Expression Directly
If your use case is simple, you can directly reference the expression in your button's disabled field like this:
{{ auditQuestions.ready_to_submit === false }}
This eliminates the need for variables or transformers entirely and works well in most cases where the dependent component loads quickly or predictably.
Why This Happens
Retool evaluates variables at the time of initialization. If a referenced component (like a query result or state value) hasn't finished loading yet, the variable may not capture the intended value. Transformers and inline expressions solve this by evaluating after the component state is stable.
Let me know if you'd like help implementing either option — happy to walk you through it!
here the value in auditQuestions.ready_to_submit has updated to true. the transformer has picked this up and when previewing the value it shows as true.
but within the button its still showing the original false value
so the button is loading the transformer value once initially and then not reading any changes after it seems. which is strange.
Direct expression within the button throws error saying auditQuestions is not defined.
But sadly same issue. wont update the variable. button wont read the variable, transformer or the value directly from auditQuestions.ready_to_submit
ive tried storing the info into local storage.... wont store. tried 50 - 100 ms via debounce on the event trigger incase values wern't ready yet.... no luck
the issue seems to be on component level as when actually saving data to database from the custom component. this works fine
try using {{ !readyToSubmit.value }} isntead of {{ self.ready_to_submit }}. I'm kinda wondering if the output is actually a string not a boolean. Here's an example of where I've ran into this before:
As you can see, the IDE shows me a JSON object (even the string one in 1st picture says 'string' but shows an object [no surrounding quotes]), but when it comes to using it I discover it actually is being stored as a string.
if this is happening to you, it would def cause problems in any comparison used
i feel like ive hit every dead end. tried reading auditQuestions.ready_to_submit:
directly - says auditQuestions is undefined in any button or other component
via varible or transformer: variable doesnt work at all. transformer reads the value and shows in perview BUT button or any other component doesn't get the value from the transformer.... not on update anyway.
ive tried via event trigger to set variable, using direct value. usin transformer value... same problem
ive tried setting value to local storage. saves as "" even though review shows correct value....
kinda ran out of things to try from my knowledge... happy to try more if anyone has any ideas or if retool can confirm this is a bug in how custom components have their output values read?
I'm glad to hear you found a workaround, @Loni, but suspect that there might be a scoping issue or something similar at play. Whenever one of my custom components isn't working as expected, I'll often just remove and re-add it to the canvas.
There doesn't seem to be an underlying systemic issue, at least, as I was able to implement something similar without any issues.
If you want another pair of eyes, I'd be happy to take a look at your app JSON and custom component code!