Are we able to update a data row in a Table Component?

We are looking to update a data row in a table after an action is fired on it. Is there a way to do this. The goal is to not refetch the entire data set.

In this scenario there is row action which updates the status of the record. Once the request comes back from the database we would like to update the row of data in the table to reflect the new value(s). Is it possible to update a single row through code?

In this particular case we don't want to use row editing functionality of the Table Component as a push-button update is desired, not fiddling around with specific columns of data.

Thank you,

Brett

Upon further investigation it looks like we can get the index of the selected row, which is the row the action is being taken on. So get the table data, update the row based on the index and table.setData() it all back in. Seems clean enough. Is this the advisable approach?

Thank you,

Brett

Hi @brettski! That sounds like a good approach

If you're using a Custom Column (button column type), you also have access to the magic variable i, so you could trigger a query updating the corresponding row (tableName.data[i])

1 Like

I have a modal for each row, and I want to change one of the rows when you close the modal. I'm using @brettski approach, but setData resets the other fields. STR:

I edit an editable column A. Then I open the modal. The query that runs when it closes changes the row (by accessing my_table.data[my_table.selectedRow.index]) and then sets the data again (my_table.set__data(mytable.data)). By doing that, I lose the changes at column A.

Are you saying that it resets the data in the other fields in that row? It isn't clear to me what is being changed you are not expecting, other fields in the row, or other rows in the table.

What is your modal doing, changing one/many fields?

The problem is that all data of the table gets reset.

This is an example of the code that I run when I close the modal. Essentially, I want to do a manual change on some data of the table:

const data = table1.selectedRow.data
data.b = 'wadus' // this won't work

const allData = table1.data
allData[1].b = '2wadus'
table1.setData(allData)
modal1.close()

When I run setData, I would expect (1) only the 2wadus value to change, and (2) the "save" button to be there.

Here's a video that shows the behaviour: video1549149374.mp4 - Google Drive

Thanks!

As you see the 2wadus is being updated in the table data. My guess on why the other values change back is because changed data is still in a 'dirty' state, not saved back to the table data. The columns you updated weren't saved to the table data prior to grabbing the data in the modal code.

Yep. That "dirty state" can be read at table.recordUpdates, so merging both table data and that would lead to the final state of the table to be correct. But if you do that, the save button is gone, because setting the data resets the dirty state.

We can workaround that by not relying on the save button, but it feels like this is becoming too complicated for something that looked simple, so maybe my approach is just wrong. Open to suggestions :slight_smile:

I am not sure what you are trying to achieve with the modal, etc.

@juanignaciosl I am facing the exact same problem. I want to update a column based on the value of another editable column i.e. if I change the tag in colA to Approved, I want colB to be populated with the amount found in colC - colB is editable so I can change the "default" if need be.

Only setData allows to update, by actually replacing the whole rowset. Not efficient as this creates a copy in memory instead of truly updating only the rows affected.

One must also ensure to include the changeSet in the data to be updated, otherwise you lose them as you have noted. Lastly to your point, the save/cancel buttons are removed as a reset is not a change (anymore).
So you really are forced to update the source instead and re-read the query for every update. Very inefficient and the bulk update cannot be used.

No reaction from Retoolers so I guess it is what it is.

I would like to do the same (update one row after a query without fetching the entire dataset) in the new tables, but there is no documentation how. Does setData() work in the new tables?

Hi @Nancy_Ts we're tracking requests for .setData on the new table, but it's not something we've implemented yet. Thanks for the feedback! The current workaround for setData is to populate a temporary state variable with your table data. Temporary state can then be manipulated using setValue or setIn, as needed.

I'm taking another look at this original thread as well :slightly_smiling_face: thanks for re-surfacing

First, thanks all for sharing some insight into how you're using - or wanting to use- the table!

I'd like to share some context with everyone on how we're thinking about the table internally. As Nancy noted, our team recently launched a new table component. As part of launching this updated table, we did a ton of research on how our customers are using tables and what use cases need to be supported. The 2 most common approaches to editable tables are to either use a form to update individual selectedRows of a table or to do a bulk update with the save changes button. In both cases, the most common approach is to have the app write back to the resource and then re-fetch the resource data in order to show the user the changes were saved. Given these are the most common approaches, these are the use cases that were prioritized first when designing the new table. They're also the approaches that are best supported in the legacy table. Just wanted to share some context on why other editing approaches can feel a bit hacky currently!

That said, we definitely want to hear about these use cases where the editing functionality is a bit different or more complex! We are interested in continuing to iterate on our table, and hopefully we can add functionality to support other ways of editing data. We're discussing something similar over here.

In regards to the more nuanced use cases described in this thread, it sounds like the most supported solution is to update a single row locally upon button click, and then re-fetch the full, updated dataset on page load. In both tables, we do not currently support programmatically updating the changeset, so it's tricky to rely on that data/using the save changes button. The legacy table supports setData, but the new table doesn't have this api yet.

For the new table, here's what I'm thinking for the temp state idea:

1). Populate a temp state var with your table query + display the temp state in the table (tableData):

2). Create a second temp state var to remember your changeset data (databaseChanges)

3). Create an action column with two event handlers. The first one will update the temporary state with the edited value, immediately reflecting in the table data. The second event will pass the edited value to the second temp state var so that you can keep track of changes.

There are some issues to keep in mind here. We have a bug with the new table where the changeset array does not clear automatically when the table is populated by temp state so you have to manually clear it

Depending on your use case, it might also be easier to use a listView (I'd only recommend if you have less than 100 rows). That way, you could also set the values of other components (could be helpful for the colB, colA example)

2 Likes