AG Grid: Delete row AND update rowData?

Hi!

I have 3 buttons:

  • add row
  • delete row
  • save (to SQL)

First two (adding and deleting rows) are in the same callback.
Here is the code for that callback:

@callback(
        Output("sql-table", "rowData"),                      #<======== not updating?
        Output("sql-table", "deleteSelectedRows"),
        Output("selected-data", "rowData"),
        Input("delete-row-button", "n_clicks"),
        Input("add-row-button", "n_clicks"),
        State("sql-table", "rowData"),
        State("sql-table", "selectedRows"),
        prevent_initial_call = True
)

def update_dash_table(n_dlt, n_add, data, selection):
    if ctx.triggered_id == "add-row-button":
        df=pd.DataFrame(data)
        new_row = {
            "test": [x],
        }
        df_new_row = pd.DataFrame(new_row)
        if df.empty == False :
            df_new_row.columns=df.columns
            updated_table = pd.concat([df, df_new_row], ignore_index=True)
        else:
            updated_table = df_new_row
        return updated_table.to_dict("records"), no_update, no_update

    elif ctx.triggered_id == "delete-row-button":
        if selection is None:
            return no_update, no_update, no_update
        return no_update, selection, selection                #<==== problem here?

Data itself is coming from another callback which in its turn is pulling data from SQL.
When I click “add row” and then “save”, row is added and data (incl. the new row) is saved to SQL. It works.
When I select row, click “delete row” and then “save”, selected row is deleted and data (excl. the deleted row) is saved to SQL. It works.
Problem arises when I combine. Example: when I add two rows by clicking “add row” twice and then, for example, delete one of these rows (by selecting and clicking “delete row”) and ONLY THEN click “save”, I hope that the newly added row that I chose not to delete will still remain and will be saved. But it doesn’t work. None of rows is saved.

I believe, it is due to no_update in the line return no_update, selection, selection.

I think what happens is: no_update in the line return no_update, selection, selection doesn’t allow Output("sql-table", "rowData") to be updated.

Is there a way to force an update to Output("sql-table", "rowData") after deleting a one of rows (but still keeping the other row) ?
Is there any alternative to no_update ?

Thanks for any replies and suggestions in advance.

Hello @mrel,

Try using rowTransaction instead.

2 Likes

Hi @jinnyzor ,

Tried following the documentation .

Adjusted the code:

@callback(
        Output("sql-table", "rowTransaction"),
        Output("sql-table", "deleteSelectedRows"),
        Output("selected-data", "rowData"),
        Input("delete-row-button", "n_clicks"),
        Input("add-row-button", "n_clicks"),
        State("sql-table", "rowData"),
        State("sql-table", "selectedRows"),
        prevent_initial_call = True
)

def update_dash_table(n_dlt, n_add, data, selection):
    if ctx.triggered_id == "add-row-button":
        df=pd.DataFrame(data)
        new_row = {
            "test": [x],
        }
        df_new_row = pd.DataFrame(new_row)
        return {"add": df_new_row}, no_update, no_update
        # return {"add": df_new_row.to_json(date_format='iso', orient='split')}, no_update, no_update

    elif ctx.triggered_id == "delete-row-button":
        if selection is None:
            return no_update, no_update, no_update
        return {"remove": selection}, selection, selection

Deleting the row works.

Now there is a problem with adding a row.

If I use return {"add": df_new_row}, no_update, no_update then I am getting an error:

File "C:\Users\PC Desk\AppData\Local\Programs\Python\Python310\lib\site-packages\dash\_validate.py", line 238, in _raise_invalid    raise exceptions.InvalidCallbackReturnValue(
dash.exceptions.InvalidCallbackReturnValue: The callback for `[<Output `sql-table.rowTransaction`>, <Output `sql-table.deleteSelectedRows`>, <Output `selected-data.rowData`>]`
                returned a value having type `dict`
                which is not JSON serializable.


The value in question is either the only value returned,
or is in the top level of the returned list,

                and has string representation
                `{'add':    entry  year      month  day category1 category2 name comment quantity price delivery amount link      
type concatenate
0     27  2023  September   16                                                                       expenses           x}`       

                In general, Dash properties can only be
                dash components, strings, dictionaries, numbers, None,
                or lists of those.

If I am using return {"add": df_new_row.to_json(date_format='iso', orient='split')}, no_update, no_update to turn the df to json, error is disappearing, but at the same time row is not getting added. Nothing happens. No error, no added row.

Any idea why it could be happening?

I normally just return a list from df_new_row.to_dict('records')

1 Like

Ok, that worked. Error disappeard.

Also it allowed me to find a bug in my “save” button. Now everything works as intended.

Thank you!

1 Like