1
votes

In Material-UI's website Table page, there's one specific table that I was interested in using for a project, labeled material-table (https://material-ui.com/components/tables/#material-table). It's got a search bar, a button for adding new rows, and the possibility of editing or deleting existing rows, also through buttons. In the site, everything works perfectly, but the source code provided doesn't, and I'm not sure why.

import React from 'react';
import MaterialTable from 'material-table';

export default function MaterialTableDemo() {
  const [state, setState] = React.useState({
    columns: [
      { title: 'Name', field: 'name' },
      { title: 'Surname', field: 'surname' },
      { title: 'Birth Year', field: 'birthYear', type: 'numeric' },
      {
        title: 'Birth Place',
        field: 'birthCity',
        lookup: { 34: 'İstanbul', 63: 'Şanlıurfa' },
      },
    ],
    data: [
      { name: 'Mehmet', surname: 'Baran', birthYear: 1987, birthCity: 63 },
      {
        name: 'Zerya Betül',
        surname: 'Baran',
        birthYear: 2017,
        birthCity: 34,
      },
    ],
  });

  return (
    <MaterialTable
      title="Editable Example"
      columns={state.columns}
      data={state.data}
      editable={{
        onRowAdd: newData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              setState(prevState => {
                const data = [...prevState.data];
                data.push(newData);
                return { ...prevState, data };
              });
            }, 600);
          }),
        onRowUpdate: (newData, oldData) =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              if (oldData) {
                setState(prevState => {
                  const data = [...prevState.data];
                  data[data.indexOf(oldData)] = newData;
                  return { ...prevState, data };
                });
              }
            }, 600);
          }),
        onRowDelete: oldData =>
          new Promise(resolve => {
            setTimeout(() => {
              resolve();
              setState(prevState => {
                const data = [...prevState.data];
                data.splice(data.indexOf(oldData), 1);
                return { ...prevState, data };
              });
            }, 600);
          }),
      }}
    />
  );
}

The code above is the one shown on the site. When I try to use it, however, while the Edit button allows me to change the fields of the selected row, the changes are not saved when I use the Save button.

Also, the Delete one seems to always delete the last row of the table, even if it wasn't the one I chose to delete. Adding new rows, however, seems to work normally.

How can I fix this?

1
You might want to console log the value of data.indexOf(oldData) because I suspect it isn't working like you intend. You may want to do something like data.findIndex(e => e.name === oldData.name). - Dillan Wilding
Same problem here! Have you found a way? - Daniele

1 Answers

0
votes
const data = [...prevState.data];
data[data.indexOf(oldData)] = newData;     

I changed it into:

const foundIndex = oldData.findIndex(x => x.name === newData.name)
data[foundIndex] = newData
return data