Changes to vars in "disable query" statement now cause queries to fire?

Is this new, expected behavior?

  • Given a query that has "run query automatically when inputs change"

  • And also has a "disable query" statement such as {{state1 < 3}}

  • Anytime one of the values of the variables in the "disable query" statement change, the query reruns. In this example, if state1 changes in value, the query reruns

  • Previously changes to variables in the "disable query" statement did not cause the query to rerun

This change is causing quite widespread breakdown of many of our apps. Thanks

Hi @aviator22 our team wasn't able to repro this, do you mind DMing so they can help you out?

I did that on Friday and included a minimal reproducible example app. Maybe the person in charge of our ticket is on break, but haven't heard back since Friday.

This breaking change is dramatically negatively affecting our primary API performance, because it's causing 10 - 20x more API calls to hit our API gateway (we use the "disable query" feature extensively to only run queries when they actually need to be run).

I've posted in the feature requests section before pleading for your team to slow down and reduce major breaking changes; it seems like that pleading has fallen on deaf ears.

Hey, just want to report here that we have a ticket open for this and will pass it along in this thread when there's a fix!

@Kabirdas Thanks for bringing this to the team for resolution. I am also trying to use a combination of:

  • "run query automatically when inputs change"
  • "disable query" with some conditions

The main reason being that it becomes hard in larger, more complex apps to ensure all of the necessary API calls are run if you resort to manual triggers. Automatic triggers make things much more manageable, but it would be great for app performance if the disable logic was respected.

Hey @davidajetter! Just want to pass along an update here.

Our team has been investigating this and it looks to be that at the moment, disable logic is respected, however, inputs to the disabled logic are also seen as inputs to the query and can trigger a rerun.

So if, for instance, your disabled logic is {{state1 < 3}} and state1 is recalculated with a value of 2 the query will be rerun regardless of where or not there are other changes (note that this happens even if the previous values of state1 was also 2 as the recalculation of the transformer is what triggers the query, not the change in value). However, if state1 is recalculated with a value of 4 the query will look to trigger, but since it's disabled it will not actually run.

We totally understand that this may not be desirable, however, since the particular behavior described above looks to have been around since 2.73.11, changing the behavior could result in breaking people's apps that are dependent on it.

If you'd like for your queries to trigger only when certain values change you can try setting it to "Run only when manually triggered" and using the "Watched inputs" field in the query's advanced settings:

These decisions by Retool are baffling. There already are broken apps running right now due to this bug. Ours were. Our apps were running queries left right up and down when they shouldn't have been. That is not good.

By fixing a bug like this you're not going to break applications, you're going to fix broken applications. All your team has to do is:

  1. Notify users "hey there's this bug, you should know about it, we're going to deploy a fix on DATE. you should know that it may change the behavior of your apps"
  2. Deploy the bugfix

Additionally baffling is that your team knows about this critical bug (retool making completely unexpected API calls by error is....critical) and still doesn't mention it in your docs.

Yea, it's really good that you were able to get your apps to a place where they weren't running queries as excessively.

Right now, we state in our docs that an "input" is a value inside of a {{}} tag anywhere inside the query panel (you'll notice the same behavior if you change the value of the failure condition message for example) which is consistent with this behavior and suggests that it's not actually a bug. That was something I didn't realize, not having seen queries used in that way, but it's very possible that other people have and are using it in other important ways we might not be able to predict.

Our docs team will take a look at how to at least make this clearer so that other users don't run into the same situation you had to navigate.

Edit:
Here's the updated section of our docs!

Hi there!! Any news about this topic? I am trying to use the "Watched Inputs" but it only allows to observe something related to "Disable query".

Hey @DavidG!

Would you mind posting a screenshot of your query along with the inputs you'd like to watch?

One thing to be aware of is that watched inputs have to actually be referenced somewhere within the query configuration, if you'd like to have other inputs trigger the query you might want to look at using event handlers instead.

Curious to see what you have otherwise!

Hey @Kabirdas! Sorry for the late response.

Here I have posted my problem with more details. Just tell me if you need more :slight_smile:

Error in Disable Query - App Building - Retool Forum

I'm also interested in a solution for this. My use case is a bit different:

  1. I have some data whose initial value is populated by the results of a GET query
  2. I have an update query that is bound to that data and is set to "run automatically when inputs change"

What I am observing is that the update query fires when the get query completes. This makes sense since the observed data goes from Null -> Not Null when the data is fetched from the server. However the Not Null value is exactly what's already stored on the server so that update is redundant and wasteful.

I tried a few things with the "disabled query" field including something like this:

  1. have an allow_updates temporary value with initial value of false
  2. set update query's "disabled query" value to {{ !allow_updates.value }}
  3. have the get query set allow_update to true from its success handler

I observed that as soon as the disabled_query value changes, it forces the update query to execute immediately. I even tried to delay setting the allow_updates by 10 seconds and it still gets fired as soon as the temporary value changes.

Is there a way to do this without triggering a wasteful update on every load?

Hey @sebmartin!

What user interactions should be triggering the update query?

I personally really like using "Run query only when manually triggered" together with event handlers and JavaScript queries to control when the query fires. However, I can imagine a case where that isn't the best solution but there may be another object that's good to watch.

Would you mind sharing a bit more about your use case?

The usecase is as simple as I described it.

  • We have an object that is initialized from a query response (the value lives in a database).
  • We want to trigger a query whenever this object is mutated

However, we want to ignore the first update which is when the GET query initializes the object to its initial value (Null to Not Null).

I thought the disabledQuery value could help us ignore initial update events like this but it looks like those update events just get queued and fire whenever the query is enabled again. This is a surprising behavior.

Alright, one thing you can try is to set up an independent watcher for the mutable object using a Query JSON with SQL query:

The query will run whenever the object mutates so you can use its success handler to prompt any kind of logic you want, acting as a more general change handler. In this case, you might set a separate tempstate to act as a counter as you initialize your app:

Since object_watcher is set to run when inputs change it'll run automatically when the app starts, then again when you run the query that initializes the object, and then again whenever the object changes after that. This means it'll run twice before the object has initialized. You can use that counter as the disabled condition on your query:

Once things have been initialized you won't want to set the initialization counter anymore:

conditionally_triggered_query.json (13.1 KB)

Let me know if that works! This is just one approach you can take. For instance, you might want to set query_to_trigger to run only when manually triggered and then have a script success handler on watcher that can conditionally trigger the query using more complex logic.

@Kabirdas Thanks, I hadn't considered the Query JSON with SQL approach. That's neat. I think however that this suffers from the same issue I was having before. It successfully disables the query on init but as soon as the count increases past the threshold to enable the query, the update fires even if I don't update the field. It seems like the init events are queued and as soon as the query is enabled they get fired. This is what I did:

  1. Initialize the counter to -10 so that it clearly stays within the update disabled threshold
  2. Load the page and inspect the console for updates... no update was triggered on load
  3. From the console, run the command: initialization_count.setValue(10) to clearly put it on the other side of the threshold.
  4. The update query fires immediately despite not having mutated any values

Can you reproduce this? Is this a bug?

It's a bit of a hacky workaround :sweat_smile: ... The idea is that the trigger from the initialization counter should replace the trigger from the first instance of the object mutating, and from then on it should be disabled.

So, the first time the query is triggered is by the initialization counter, and from then on it's from object mutations.

object_watcher runs automatically on page load setting counter to -1 (query doesn't trigger)

mutable_object is initialized (query doesn't trigger)

object_watcher runs setting counter to 0 (query doesn't trigger)

mutable_object is changed (query doesn't trigger)

obect_watcher runs setting counter to 1 (query does trigger)

... from here on object_watcher no longer runs

mutable_object is changed (query does trigger)

mutable_object is changed (query does trigger)

... etc.

-------

If the mutable object is the only thing that should be triggering the query, a nicer setup might be to set the query to run only when manually triggered and have object_watcher trigger it as a success handler.

1 Like

I'm running into this issue as well. I'm finding these workarounds really unwieldy and they will make my apps more prone to bugs. Is there anyway you can add a setting for the app so that people that run into this issue can click a checkbox and the app will behave as expected? This way existing apps don't break and people having this issue don't have to work around it.

Hey @Jazon_Yamamoto!

There is an internal ticket for changing the behavior here but there isn't a timeline on it at the moment. I've bumped it and if it is included can let you know here!

Running into this issue as well, on load the app just runs all queries even tho they all have a true value in the disable query, this causes tens of errors per page load, not good