In my MUI DataGrid Pro I have two action buttons in every row they should change depending wether the row is in edit or view mode. I copied the demo code from MUI and I adapted it to add the row to my database.
Everything works well and the row is added to the database but the buttons change back to the view mode for a split second an then they are back in the edit mode.
The onProcessRowUpdateError returns this.
TypeError: Cannot read properties of undefined (reading 'id')
at getRowIdFromRowModel (gridRowsUtils.js:30:1)
at gridRowsUtils.js:154:1
at Array.forEach (<anonymous>)
at updateCacheWithNewRows (gridRowsUtils.js:153:1)
at useGridRows.js:118:1
at Proxy.updateRows (useGridApiMethod.js:14:1)
at useGridRowEditing.js:390:1
column definition:
const actionColumns = [
{
field: 'actions',
type: 'actions',
headerName: 'Actions',
width: 100,
cellClassName: 'actions',
getActions: ({ id }) =>
{
const isInEditMode = rowModesModel[id]?.mode === GridRowModes.Edit;
if (isInEditMode)
{
return [
<GridActionsCellItem
icon={<SaveIcon />}
label="Save"
sx={{
color: 'secondary.main',
}}
onClick={handleSaveClick(id)}
/>,
<GridActionsCellItem
icon={<CancelIcon />}
label="Cancel"
onClick={handleCancelClick(id)}
color="white"
/>,
];
}
return [
<GridActionsCellItem
icon={<EditIcon />}
label="Edit"
onClick={handleEditClick(id)}
color="white"
/>,
< GridActionsCellItem
icon={<DeleteIcon />}
label="Delete"
onClick={handleDeleteClick(id)}
color="white"
/>,
];
},
},]
Clicking the add button
{
// Create a new row object with a unique ID and default property values
const id = uuidv4();
const newRow = { id, reg_name: "", reg_created: '', isNew: true };
setRegions(oldRegions => [newRow, ...oldRegions]);
setRowModesModel((oldModel) => ({
...oldModel,
[id]: { mode: GridRowModes.Edit, fieldToFocus: 'reg_name' },
}));
setIsNewRow(true)
}
Click the save button
const handleSaveClick = (id) => async () =>
{
console.log('save click')
setCurrentId(id);
setRowModesModel({ ...rowModesModel, [id]: { mode: GridRowModes.View } });
};
Triggers the process row update
async function processRowUpdate(newRow)
{
console.log('process row update')
const updatedRow = { ...newRow, isNew: false };
if (rows)
{
setRows(rows.map((row) => (row.id === newRow.id ? updatedRow : row)));
}
// New record
if (updatedRow, isNewRow)
{
console.log('add new region')
const regName = updatedRow.reg_name
try
{
const data = await APIServiceRegions.addRegion({ regName })
}
catch (error)
{
console.error(error);
}
setIsNewRow(false)
}
// Edited record
if (updatedRow, isEditedRow)
{
console.log('edit region')
const regName = updatedRow.reg_name
try
{
const data = await APIServiceRegions.updateRegion({ currentId, regName })
}
catch (error)
{
console.error(error);
}
setIsEditedRow(false)
}
};
Sets the rowModes
const handleRowModesModelChange = (newRowModesModel) =>
{
console.log('handle row modes model change')
setRowModesModel(newRowModesModel);
};
This is the component view
<DataGridPro
sx={{
borderColor: 'white',
'.MuiDataGrid-columnHeaders': {
borderBottom: 'solid',
borderBottomColor: 'white'
},
}}
rows={regions}
key={regions.id}
columns={[
...RegionsColumns, ...actionColumns
]}
editMode="row"
initialState={{
...RegionsColumns.initialState,
columns: {
...RegionsColumns.initialState?.columns,
columnVisibilityModel: {
reg_id: false,
}
}
}}
slotProps={{
toolbar: { setRows, setRowModesModel },
}}
onRowSelectionModelChange={handleSelectionModelChange}
rowSelectionModel={selectionModel}
rowModesModel={rowModesModel}
onRowModesModelChange={handleRowModesModelChange}
onRowEditStop={handleRowEditStop}
processRowUpdate={processRowUpdate}
onProcessRowUpdateError={(error) => console.log(error)}
hideFooter={true}
/>