What are suggested component+data source setups for showing nested arrays?

tl;dr:
Retool seems to work good OOTB for presenting requests that return [{key:value}] or [{key:{key: value}}]
but
Whenever request contains [{key:value, additional_objects:[{key: value},{key: value}]}] it either requires haxes or significantly degrades UX.

Hi!
In the past I’ve made Retool apps that only ever handled back-end responses containing arrays with nested objects that at worst had relation of 1:1 (each row/array’s object had exactly one child object) so displaying, styling and editing it wasn’t ever an issue due to me always being able to reference parent table (via currentRow/selectedRow, self or item) for everything. Aside from a known Retool bug on styling hidden vs disabled due to different contexts :salt:)

My usual flow was:

  • parent table, with togglable rows
  • child tables (inside of tabbed component,) for (every) nested object (using {{currentSourceRow.subarrayKey}})

However recently I needed to create apps that aimed to showcase more complex relations where each row contained an array of related objects and setup of:

  • parent table, with togglable rows
  • child tables (inside of tabbed component,) for (every) nested array of objects

and above setup doesn’t seem to cooperate well with Retool table component assumptions.

Examples:

1. 1:1 relation
(here everything works, since you can easily reference parent table and just drill down to a specific key-value)

BE response pattern:

[{"id": 1,"credentials": {"id": 111,"inserted_at": "2025-08-05T13:38:34",},"inserted_at": "2025-02-13T13:54:38","workspace_id": 6720,"project": {"id": 2119,"location": "United States","inserted_at": "2025-01-07T12:27:52"},"map": {"id": 8858,"state": "done","inserted_at": "2026-02-18T16:37:16"},"last_edited_at": "2026-02-18"},...]

Things I need:

  • Button components outside of child table that trigger per row actions (ex. getting map’s id for request using {{tableName.selectedRow.map.id}})
  • styling of parent rows based on child table rows

Things that work:

tl;dr - here all works smoothly. :smiley:

  • Button components outside of child table that trigger per row actions (ex. getting map’s id for request using {{tableName.selectedRow.map.id}})
  • styling of parent rows based on child table rows (using references like {{currentRow.project.location}} for row color)

2. 1:n relation with specific UX/styling requirements
(here’s where most of things aside from listing breaks, since using {{currentRow.arrayName}} as data source still makes table work in context of entire parent table instead of just currentRow data)

BE response pattern:

[{"members": [{"active": true,"inserted_at": "2023-07-03T11:33:11","email": "test1@gmail.com","role": "owner"},{"active": true,"inserted_at": "2023-11-06T14:33:15","email": "test2@gmail.com","role": "member"},...],"organization_id": 16202,"workspaces": [{"id": 11765,"name": null,"inserted_at": "2023-10-16T15:07:50"},{"id": 53175,"name": "Say my name","inserted_at": "2026-01-12T11:13:26"}],"organization_name": null},{"members": [{"active": true,"inserted_at": "2023-10-25T13:41:30","email": "test+20@gmail.com","role": "owner",},{"active": false,"inserted_at": "2024-08-05T14:09:24","email": "test1@gmail.com","role": "member",},...],"organization_id": 16658,"workspaces": [{"id": 12217,"name": null,"inserted_at": "2023-10-25T13:41:30"}],"organization_name": null},...]

Things I need:

  • multiselect on child table
  • styling of parent rows based on child table rows
  • styling of child rows based on child rows
  • styling custom column Buttons of child rows based on child row data
  • not running custom column Buttons event handlers depending on child row data
  • running per row actions
  • styling Button components next to child table based on child table row data

Things that don’t work:

  • multiselect on child table and batch actions always points to the same table (when referencing {{childTable.selectedRows}} will always point to one specific child table or be undefined depending on the exact place you place the reference, regardless of the true selected row/rows origin)
  • styling of child rows based on child rows (as despite child table having it’s own data source, styles are computed based on parent table’s complete array)
  • styling custom column Buttons of child rows based on child row data (again child having parent table’s complete array)
  • styling Button components next to child table based on child table row data (impossible to get this context?)

Things that work:

  • not running custom column Buttons event handlers depending on child row data (different available context that’s more local?)
  • running per row actions has same issues as multiselect, but can be haxed around using intermediary variables (so instead of request relying on table.data.key directly, I have a custom row button in child’s table, that grabs {{ currentRow.id }} via Event handler, saves it to app-wide variable, and then request uses {{ appWideVarName.value }}
  • styling of parent rows based on child table rows works only as a .filter/.map hax if you have within parent and child same exact data point to match it within JS snippets :confused:

3. 1:n relation with full CRUD requirement, including moving child objects between parents (which again breaks whenever you want to use 2 components for displaying purposes)

BE response pattern:

[{"id": 291,"name": "optimization","inserted_at": "2025-12-18T13:12:20.832Z""prompts": [{"id": 1293,"text": "What questions do you ask AI?","inserted_at": "2025-12-18T13:12:20.832Z"},...]},{"id": 299,"name": "apple","inserted_at": "2025-12-18T13:12:20.832Z""prompts": [{"id": 1299,"text": "Why Macbooks have stupid NAND memory integration designs?","inserted_at": "2025-12-18T13:12:20.832Z"},...]},...]

Things I need:

  • adding a new object to parent table/array (including cases where rows can have incomplete kvs)
  • adding a new object to child table/array (including cases where rows can have incomplete kvs)
  • editing values on parent table
  • editing values on child table
  • moving objects between child tables/arrays
  • deleting objects in child table
  • deleting objects in parent table

Things that don’t work:

(to attempt full CRUD without multiple different UX actions and multiple saves I attempted to make a app-variable that would have working copy of data I modify with UI elements, instead of using request.data and Retool’s built-in change sets)

  • adding a new object to parent table/array (not compatible with how Retool handles select editable columns, as appending new data to variable that’s table source triggers edit mode automatically?)
  • adding a new object to child table/array (-||-)
  • moving objects between child tables/arrays (not supported?)
  • deleting objects in child table (impossible if attempted within same move as add?)
  • deleting objects in parent table (-||-)

Things that work:

  • flattening BE output into cartesian object and then redoing object layout back up before sending update POST request (*maybe would work, but is very error prone in my PoC attempts)
  • editable JSON field (but that heavily depends on users requiring JSON editing knowledge and providing logic and syntax-wise a correct code on every edit :confused: )

I’ve been attempting to gracefully solve both 1:n nested arrays cases and I’m kinda lost, hopefully I’m missing something obvious - thank you in advance for any insights/suggestions. :folded_hands:

Cheers!