How does the CellChangeHandler of a Table work?
I found the possibility to use the cellChangeHandler to save an individual cell, but I cannot find any documentation on this. When trying to save data from this, I just receive the following error:

update `Employees` set `statusCode` = 422, `error` = 'Unprocessable Entity', `message` = 'A changeset must be specified', `data` = NULL, `queryExecutionMetadata` = {"estimatedResponseSizeBytes":103,"resourceTimeTakenMs":54,"isPreview":false,"resourceType":"mysql","lastReceivedFromResourceAt":1664371659608}, `source` = 'resource' where `id` = 733 - ER_BAD_FIELD_ERROR: Unknown column 'statusCode' in 'field list'

Using the following statement in the cellChangeHandler of a table, where data has been changed

How does this method work?

Hey @ObiOne,

What's inside your table1CellChangeHandler query?

You still need to get the edited parts of your table via recordUpdates and changeSet. recordUpdates will give you the whole row that was updated while changeSet only the column that was updated. You can combine these to fit your scenario.

This get's a bit tricky when you update multiple cells in succession, I would use the Save Changes handler instead.

Does that make sense?

The screenshot above shows what is currently inside the table1CellChangeHandler. I am using the GUI query here, as it is easier to get where I want in this instance.

I changed this to {{ table1CellChangeHandler.changeset }} or {{ table1CellChangeHandler.changeset }}, but it still tells me a "changeSet has to be specified". As I do not know here which column is being edited, I hoped the changeSet would contain a key:value pair, but only contains a String?

The SaveChanges will be my last resort, but for that I would have to reformat the column name of every table, since the displayed value is a String, but the corresponding database contains a number (respective Foreign Key) to another table with another name for the column.

Ohh, so you can't access the queries data inside the same query before it's run. It would always result in an error.

the recordUpdates and changeSet values are accessible via the table component, not the query.

Meaning, if you're table has an id of employees you would access the changes via

  • employees.recordUpdates
  • employees.changeSet

Both variables contain key/value pairs

You can parse the string as an integer to get a number if you'd like with parseInt(yourColumnId)

Ah, yes... :see_no_evil:
You are right. Ok, last thing:
Is there a way to give each column of a table a different label for a column than its technical name?

Background: the frontend-table is displaying the value it gets from a union with another table.

SELECT e.name, o.office_location
FROM employees e
LEFT OUTER JOIN office o ON o.id = e.office_id;

If I update the office_location I want to update e.office_id and not office_location, which is in the table office, which is only referenced.


You'll need a JS query that formats the data as you want it before sending it to your DB query.

So when a cell change or save event gets fired you can take the office_id and update your employees table with it.

Ok, thanks. I solved it in another way, by not-joining the tables, but displaying the id using the "dropdown" feature of the table, which matches an id to a label/caption received by another table.

I've been using Retool for a few weeks, and love how it's allowing us to prototype so quickly. However, when we want to do custom code, it takes 10x longer to do simple stuff than if it was being done in React. This is a classic example of where retool needs to update it's game with regards to documentation. I'm creating an event handler for when a cell changes. How do I get the context? What changed? How do I access the current row etc.? I can't think of an example where you would want an event handler for when a cell changes, and not to have some context data of what changed. The docs don't seem to show anything, and the UI doesn't have any suggestions. This would be a huge benefit to add in, please.

@readikus there is a lot of documentation about editing tables and making updates in a table. Additionally, there is a new table component being developed to add flexibility similar to what you mention above....

Thanks for the link, but they don't cover my usecase. The calculations needs to re-run when the value for another cell changes. We have an editable text field, and want another column to show the number of characters in that field. So when the text changes, we ideally want the count to update in real time. It is acceptable to have it run once the field loses focus, but again, getting this to work in the handler is painful and documentation is limited.

Hey @readikus!

Adding event context to handlers is on the radar for our devs and will possibly be included down the road. I can let you know here if it is!

In the meantime, it might be helpful to use the changeSet property of your table. You could, for instance, use a mapper like:

{{table1.changeSet[i]?.name?.length ?? currentRow.name.length}}

The variables i and currentRow will refer to the index and underlying data of the current row, respectively. The value of currentRow won't change with edits but the changeSet will.

Could that work for your use case?

update_column_on_change.json (12.6 KB)

Amazing - worked well. How would I have known about those variables (i.e. i for the current row) within the code editor?


You can find a list of table properties with their descriptions in the table component docs, these same descriptions are available as tooltips in the State tab of either the left panel or your debug console:

The currentRow variable isn't mentioned there explicitly though it does show up in the common table variables section of the docs and in autocomplete:

At the moment, a good way to navigate the docs is to start from a high level, thinking about what you want the user interaction to be for instance, and then drill down into specifics. For quick lookups you can check pages like JavaScript API and component doc. You might also be interested to see a list of reserved object names.