Queries that should run only when manually triggered are running on page input change

Some queries in my app despite being triggered only when manually triggered are still running on page load or input being changed.

  1. The flag in advanced for run on page load is disabled.
  2. Even when query is disabled in advance it is still running on page load.
  3. When I duplicate the query the duplicate is behaving the same way.
  4. Once the reference {{Table1.selectedRow.id}} is removed from filter the query stops this behavior.
1 Like

Hi @Fedor ,

This is strange behavior. I know you already stated that these queries are being triggered only when manually triggered, but I just want to check if what you mean by this is the set up within the "Run Behaviour" section is set up to "Manual".

The fact that you say that when you remove the varaible ffrom the filter is what makes it trigger makes me thing that it is still set up to automatic (i.e. "Query runs on page load or when a variable it depends on changes")

Miguel hi, thank you for reacting. Please see below some more info.
The query is:


The advanced section is:

When i reload page or change input in Deals table the following error appears:

Now even if i disable this query this error would keep appearing:

But as soon as i delete the below reference the error would dissapear even with the mentioning in Confirmation message section.

Hi there @Fedor ,

Thanks for the additional insight.

So, you want to add the ? operator to all your variables, e.g. {{VesselInfo.selectedRow?.vessel_name}} so that it returns undefined rather than error when there is no selected Rows (and you won't get the linting error anymore).

The fact that you're getting the linting error doesn't mean the query is running, it is just informing yuo that one of your variables is not correct, but the ? operator should fix that.

If instead the query is ACTUALLY being triggered, you can see in your console what is it that it is triggering it, maybe an event in your table upon Row Select??

1 Like

ah, so

tldr;
to fix, change {{ VesselInfo.selectedRow.shipment_id }} to something similar to one of the below. the difference is we check if .selectedRow exists before we try to access .shipment_id and we give a default value for when it doesn't exist or when it's null:

  • {{ VesselInfo.selectedRow?.shipment_id }} this is technically null, but it can actually be read as an empty string ''
  • {{ typeof VesselInfo.selectedRow == 'object'? VesselInfo.selectedRow.shipment_id : "Default Value" }}
  • {{ VesselInfo.selectedRow != null? VesselInfo.selectedRow.shipment_id : "Default Value" }}
  • {{ VesselInfo.selectedRow?.shipment_id ?? "Default Value" }}

in this picture, the query isn't actually running. this is actually an error from the linter which, at this point where it makes the error, it's parsing your code to make sure there aren't any problems. anytime the linter does this it'll show that error (for now :wink:)

now, as far the error goes.
{{ VesselInfo.selectedRow.shipment_id }}
gives
'Cannot read properties of null (reading 'shipment_id')"

you'll see similar errors often and the problem stems from assuming an object like:

{
  key1: value1,
  shipment_id: 'abc123',
  ...
}

is always there. in your case, you are accessing the .selectedRow object of a table (i assume). after the table is created though on page load there is a point in time where the data hasn't been loaded/populated yet, which also means .selectedRow is null because there are no rows to select so .selectedRow hasn't been initialized yet (we know it exists, but we won't know what type it will be until it's given a value. this is like having var myVariable;, you know it exists but it's value is null because we haven't assigned anything to it yet). after this, the data loads and the table can now set default values... normally, there isn't a row selected by default, which means .selectedRow is still null, undefined or at best an empty object{ } similar to const myVariable = {}; or

VesselInfo = {
    selectedRow: null
}
// or
VesselInfo = {
    selectedRow: { }
}

above, you can see selectedRow doesn't have shipment_id yet and in the 1st case we don't even know if it will be an object or an array (which would never have a .selectedRow). in the 1st case when you try to use VesselInfo.selectedRow.shipment_id 2 steps are taken:

  1. evaluate VesselInfo.selectedRow and pretend we save it as tempValue
  2. evaluate tempValue.shipment_id

for #1, we get tempValue = null
for #2, we get null.shipment_id.... and this is the cause of the error. null is not of type Object or: typeof null !== 'object' so it doesn't have any properties or key/values inside of it. when the linter tries reading 'shipment_id' it knows null has no properties, so it marks this error

there are a couple reasons I can think of for why {{ Deals.selectedRow.deal_name }} doesn't produce an error.

  • retool will originally color any {{ }} section green, then if the linter finds a problem it turns it yellow or red. when the linter found the 1st error, it was either unable to continue or gave up because continuing was pointless so it never got a chance to re-evaluate the last line resulting in the ui still displaying it as green.
  • the Deals component (table?) has a valid default/initial value set for selectedRow, so at no point does Deals.selectedRow evaluate to null and it will always be of type Object
1 Like

Dear @bobthebear , @MiguelOrtiz thank you so much for your feedback and kind comments.
I have finaly solved this problem after one week of back and forth, and actually I tested all your methods before as I had enough time to read most of posts related to this type of issues.
But the problem was different and now I would try to explain the bug.


There's no any errors in this part of script, but it turned out that before I was using another Action type, which off course not used for a year already, but for some reason the engine still processing it and giving errors. Please see the screen below.

I have to say it broke my brain at some stage, as even deleting and creating the query with the same name as well as duplicating saves this unused tails, even if they are not used or selected.

Thus my conclusion is - Always remove all code and don't count that if you don't call / choose it it won't work... No, it would / may (you never know).

2 Likes

How frustrating having to spend so much time for something like that! Glad you were able to figure it out in the end

Thank you all for going above and beyond figuring out the root cause of this issue. We love to see this level of teamwork! :raised_hands:

I'm trying to reproduce in order to create a report and prevent others from running into this. @Fedor, it looks like you were getting this error as soon as your app loaded. I created an empty app with a similar query and a missing reference:

I'm only getting the error when I run the query:

Were there any event handlers that were running this query at some point? Or perhaps this was happening in an older Self-hosted Retool version. If so, which version are we on?

@Paulo, the version is 3.33.3
To reproduce the issue just add another action type on the above. And both Action types would be processed even despite one of them is inactive.

Interesting, I tried on v3.33-stable and it only runs once after it's saved:

The 8 errors (twice as many) come from an error showing up when we save the query (after changing the action type) and the one from when we actually run it.

Once the query is saved, it only shows one error per run: