Expandable Row Query Context Has Changed — Existing Apps May Break

Hi Retool team,

I’ve noticed a recent change in behavior when triggering JS queries from components placed inside expandable row sections of a Table component.


:white_check_mark: Positive change:

It looks like we can now use i, currentRow and currentSourceRow inside JS queries triggered from buttons or components within the expanded row.

This is great — it's much more ergonomic than the older workaround where we had to use, e.g.

const row = table2[table1.selectedDataIndex].selectedRow;

:warning: But this may break existing apps:

Previously, it was possible to access external components in a query that was triggered from inside the expanded row, and they resolved correctly (or at least predictably). Now, when a query is triggered from inside the expanded row, references to external components like table17.selectedDataIndex appear to return null, or fail to resolve entirely, even when the same query works fine if triggered from outside the row.

For example:

const selectedImages = table18[table17.selectedDataIndex].selectedRows;

…works when triggered globally, but fails with:

Cannot read properties of null (reading 'selectedRows')

…when triggered from a button inside the expanded row — because selectedDataIndex is no longer populated in that context.


It seems like this is due to a scoping change — Retool now isolates the expanded row context more strictly (which is good), and the JS query triggered from within an expandable row no longer has access to outer table state by default.

But this change might silently break existing apps that rely on accessing selectedDataIndex or other external component state.


:question:Questions:

  1. Can you please confirm this has changed and has it now been applied to all tables, or only new ones?
  2. Is there a recommended way now to reference outer components safely from inside an expanded row component? What other variables can we use on top of i, currentRow and currentSourceRow
  3. Could there be a compatibility mode (or deprecation warning) to catch this kind of usage before apps break?

Again — the addition of i, currentRow and currentSourceRow is a very welcome improvement, and I’ll refactor accordingly. I just want to ensure this behavior is clearly understood and ideally won’t break existing apps unexpectedly.

Happy to share a minimal reproducible example if helpful.

Thanks!
Miguel

3 Likes

Hi Retool Team,

Just following up on the below, any insight would be super helpful.

Thanks
Miguel

Hi @MiguelOrtiz!

Apologies for the delay. I can definitely investigate this and get back to you.

I was under the impression that the table had not been changed, as we tend to announce any big changes such as the ones you are describing so that we can let users know and stay on top of things.

So I am curious to test this out and talk to the UI team to see if this "snuck" through or if these good and bad changes are being caused by other changes being made to the app/UI :thinking:

1 Like

Hi @MiguelOrtiz, if possible could you please attach an example app demonstrating the behavior change?

2 Likes

Hey @jacobstern,

Of course, find attached.
Untitled-9.json (137.8 KB)

I created a simple table with a nested table. INside the nested is a table. You will see how both queries react differently. The query that works from oustide the table can be run by clicking on the "Run" button of the query, but when running it from within the nested table, it will get an error.

Hope this helps!

1 Like

Hi @MiguelOrtiz,

I just tested out that app export and can confirm that the button nested within table1's rows is consistently having the 'outside' JS query fail while the 'inside' query succeeds.

And when I ran the 'outside' JS query manually it worked :face_with_spiral_eyes:

Very odd behavior, I will go over this with the engineering team. Multiple teams all reported that there have not been any changes made to the table's query calling logic so this may be a side effect of something farther removed :thinking:

I will report back with any information I hear from the team!

1 Like

Thanks @Jack_T. As a said, it is a good step forward, as long as we understand the constraints and it is consistent across components within the nested row.

Additionally, if we could somehow referred, as mentioned in other threads already, to the index of the main row (as we used to do with listViews with {{ ri }} ) it would be great!

Yes I fully agree. We should be certain about how nested components are scoped in terms of accessing the state of their 'parent' components as well as iterators.

Also to clarify, was the same nested query run able to access the parent components 'row' previously?

Are there other components like list views where an analogous set up with nested components would work?

I agree we should always allow for nested components to access the index of the top level parent component and to have parity of that across components! I will ask the engineering team on where we are on this and what limitations we have for getting this working consistently :+1:

1 Like

Hey slightly related, I’m trying to update a field on the row using a textInput on the dropdown but having difficulty targetting the textInput for the row…. value is not a recommended option on the auto complete (only plugin is).

It’s clear on the docs that items in the drop down get context from sourceRow, but it’s not clear how to target in the dropdown for that specific row in quries? Or am I meant to push it in a JS script rather than a trigger on the eventHandler