Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[data grid] How to handle nullable values for singleSelect columns? #12383

Closed
filipneculciu opened this issue Mar 8, 2024 · 4 comments
Closed
Labels
component: data grid This is the name of the generic UI component, not the React module! status: waiting for author Issue with insufficient information support: commercial Support request from paid users

Comments

@filipneculciu
Copy link

filipneculciu commented Mar 8, 2024

The problem in depth

Do you have any recommendation/best practices for handling singleSelect columns with nullable values in data grids?

Having null as a possible values leads to warnings in the console log, when switching between null and non-null values; such as:
Warning: value prop on input should not be null. Consider using an empty string to clear the component or undefined for uncontrolled components.
Warning: A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components

I have modified the code example from here: https://mui.com/x/react-data-grid/editing/#full-featured-crud to use DataGridPro and make the Department nullable. You can find the sandbox here: https://codesandbox.io/p/sandbox/elastic-fog-k829hp?file=%2Fsrc%2FDemo.tsx
To see the warning you can try to open the console log before changing to a null value in one of the cells.

In the APIs I use, I get the values as null and need to send them as null. I'd like to know if I can work with them in the DataGrid like this (which would be ideal) or I need to do some workaround (map them to something else for display and map them back when communicating with the API).

Your environment

`npx @mui/envinfo`
  Binaries:
    Node: 20.5.0 - C:\Program Files\nodejs\node.EXE
    npm: 9.8.0 - C:\Program Files\nodejs\npm.CMD
    pnpm: Not Found
  Browsers:
    Chrome: Not Found
    Edge: Chromium (122.0.2365.66)
  npmPackages:
    @emotion/react: 11.11.1 => 11.11.1
    @emotion/styled: 11.11.0 => 11.11.0
    @mui/base:  5.0.0-beta.22
    @mui/core-downloads-tracker:  5.14.17
    @mui/icons-material: 5.14.16 => 5.14.16
    @mui/material: 5.14.16 => 5.14.16
    @mui/private-theming:  5.14.17
    @mui/styled-engine:  5.14.17
    @mui/system:  5.14.17
    @mui/types:  7.2.8
    @mui/utils:  5.14.17
    @mui/x-data-grid:  6.18.0
    @mui/x-data-grid-pro: 6.18.0 => 6.18.0
    @mui/x-date-pickers:  6.18.0
    @mui/x-date-pickers-pro: 6.18.0 => 6.18.0
    @mui/x-license-pro:  6.10.2
    @types/react: 18.2.36 => 18.2.36
    react: 18.2.0 => 18.2.0
    react-dom: 18.2.0 => 18.2.0
    typescript: 5.2.2 => 5.2.2

Search keywords: singleSelect column nullable
Order ID: 70895

@filipneculciu filipneculciu added status: waiting for maintainer These issues haven't been looked at yet by a maintainer support: commercial Support request from paid users labels Mar 8, 2024
@MBilalShafi MBilalShafi added the component: data grid This is the name of the generic UI component, not the React module! label Mar 9, 2024
@MBilalShafi
Copy link
Member

MBilalShafi commented Mar 9, 2024

Hey @filipneculciu,

Warning: value prop on input should not be null. Consider using an empty string to clear the component or undefined for uncontrolled components.

The problem mentioned is with the underlying native input event, not even with the underlying material component used (Select). You can observe the same error in this example where no MUI component is used: https://stackblitz.com/edit/vitejs-vite-wbs7mo?file=src%2FApp.tsx,src%2Fmain.tsx&terminal=dev

So, by definition, you can not pass null value to the input element. A common solution proposed to the same problem would be to use the empty string '' instead (example). You can have a translation layer between FE-BE.

Frontend Side:
If you receive values like this: const roles = ["Market", "Finance", "Development", null] as mentioned in the attached example, you can have it translated to '' like so:

{
  field: "role",
  headerName: "Department",
  width: 220,
  editable: true,
  type: "singleSelect",
  valueOptions: roles.map((value) =>
    value !== null
      ? { value: value, label: value }
      : { value: '', label: "None" }
  ),
}

Backend Side:
Since the backend would expect back the null values in return, you can handle this translation in processRowUpdate callback.

const processRowUpdate = async (newRow: GridRowModel) => {
  const updatedRow = { ...newRow, isNew: false } as GridRowModel;
  const serverRow = { ...updatedRow, role: updatedRow.role === '' ? null : updatedRow.role};
  setLoading(true); // optional optimization with the `loading` prop passed to the grid
  await server.post('https://api.url', serverRow); // send the row with `null` value on server
  setLoading(false);
  return updatedRow; // return the value with `''` value on FE
};

Here's the modified sandbox: https://codesandbox.io/p/sandbox/snowy-cache-pf36j5?file=%2Fsrc%2FDemo.tsx%3A35%2C36

Let me know if it makes sense.

Thank you!

@MBilalShafi MBilalShafi added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Mar 9, 2024
@filipneculciu
Copy link
Author

filipneculciu commented Mar 11, 2024

Yes, it makes sense; this is the workaround I was thinking about in the last sentence of my paragraph. I guess this translation layer is unavoidable, I was thinking that maybe there was an option to have the DataGrid do it internally.

There is one issue that this mapping causes and it's reproducible in your sandbox (https://codesandbox.io/p/sandbox/snowy-cache-pf36j5?file=%2Fsrc%2FDemo.tsx%3A35%2C36). Open then filtering menu for the "Department" column and you'll get the following warning in the console:
Warning: Encountered two children with the same key, ``. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

I guess this is because the value is '' for both no selection and for "None". Do you have a suggestion to fix this? My only idea was to try something with non-printable characters instead of '', but this solution seems hacky to me.

@github-actions github-actions bot added status: waiting for maintainer These issues haven't been looked at yet by a maintainer and removed status: waiting for author Issue with insufficient information labels Mar 11, 2024
@michelengelen
Copy link
Member

@filipneculciu you can just use a different value instead of '' for the valueOption.

{
  field: 'role',
  headerName: 'Department',
  width: 220,
  editable: true,
  type: 'singleSelect',
  valueOptions: roles.map((value) =>
    value !== null ? { value: value, label: value } : { value: -1, label: 'None' },
  ),
},

and to adjust the parsing in processRowUpdate:

const processRowUpdate = (newRow: GridRowModel) => {
  const updatedRow = { ...newRow, isNew: false } as GridRowModel;
  const serverRow = {
    ...updatedRow,
    role: updatedRow.role === -1 ? null : updatedRow.role,
  };
  // server.post('/data', serverRow);
  return updatedRow;
};

Would that work for you?

@michelengelen michelengelen added status: waiting for author Issue with insufficient information and removed status: waiting for maintainer These issues haven't been looked at yet by a maintainer labels Mar 25, 2024
Copy link

github-actions bot commented Apr 1, 2024

The issue has been inactive for 7 days and has been automatically closed.

@github-actions github-actions bot closed this as completed Apr 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: data grid This is the name of the generic UI component, not the React module! status: waiting for author Issue with insufficient information support: commercial Support request from paid users
Projects
None yet
Development

No branches or pull requests

3 participants