I cannot have two (or more) fields with the same name when creating columns in a DataGrid of MUI
Asked Answered
L

3

1

I am creating a DataGrid where I want to show the values of ready_by and name that you can see in this picture:

Json of the data

In the code, I have configured it in this way: (focus on the last two)

const columns = [
    {
      field: 'id',
      headerName: "ID",
      minWidth: 50,
      type:"number",
      align:'left',
      hide:'true'
    },
    {
      field: 'customer',
      headerName: 'Customer',
      valueGetter: ({ value }) => value.email,
      width: 250,
    },
    {
      field: 'paid',
      headerName: 'Customer has paid?',
      width: 250,
    },
    {
      field: 'total',
      headerName: 'Cost',
      width: 150,
    },
    {
      field: 'details',
      headerName: 'Ready By',
      type: 'datetime',
      valueGetter: ({ value }) => value.ready_by && new Date(value.ready_by),
      width: 250,
    },
    {
      field: 'details',
      headerName: 'Name',
      valueGetter: ({ value }) => value[0].name,
      width: 250,
    },
  ];

The problem is that when I render the page only one of them shows up and that's because I repeat the field value. So I want to ask you how to resolve this:

Page with the Datagrid

Lemures answered 30/3, 2022 at 16:2 Comment(2)
from the docs "field is the only required property since it's the column identifier." i guess you have to change field to be unique. mui.com/components/data-grid/columnsCanaletto
How can I do that? I don't see the propertie "unique" in the column documentation.Lemures
L
2

The params object from a ValueGetter contains a row property which contains the entire model that the row is mapped from. So you can just assign a unique ID in field (doesn't have to match a property on your object), and get the value from params.row. E.g.

...
// Leave this one the same
{
  field: 'details',
  headerName: 'Ready By',
  type: 'datetime',
  valueGetter: ({ value }) => value.ready_by && new Date(value.ready_by),
  width: 250,
},

// Set a unique field and get the relevant data using the row property
{
  field: 'name',
  headerName: 'Name',
  valueGetter: (params) => params.row.details[0].name,
  width: 250,
},
...

This is much more efficient than using find() on the whole list of data since we already know the specific model for this row.

The params for a ValueGetter are of type GridValueGetterParams. There is not much documentation about this type, but according to the source, it extends GridCellParams, which contains some info about row.

Lou answered 5/9, 2023 at 21:44 Comment(1)
I'm using "@mui/x-data-grid": "^7.3.1" has changed slightly, row is a seperate prop ``` valueGetter: (params, row) => row.details[0].name ```Dicast
L
0

Yes, that is correct. The "field" is a column identifier and must be unique.

Here's my solution:

Assumption: Here data means the array you're feeding to the rows prop for the <DataGrid/> MUI component.

const columns = React.useMemo(
     () => [
       ..., // all the other elements

  
       // No changes needed here since this is the first occurrence of 'details'
       {
         field: 'details',
         headerName: 'Ready By',
         type: 'datetime',
         valueGetter: ({ value }) => value.ready_by && new Date(value.ready_by),
         width: 250,
       },

        // Here we're basically searching for the item of interest since we do get `id` as a param arg.
       {
         field: 'details2',
         headerName: 'Name',
         valueGetter: ({ id }) => {
           const item = data.find(item => item.id === id);
           return item.name;
         },
         width: 250,
       },

     ],
    [data]
  )
Lepus answered 23/7, 2022 at 1:7 Comment(0)
L
0

MUI in v7 changed this, you can do it this way:

valueGetter: (value, row, column, apiRef) => value,
Lighterman answered 23/9 at 18:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.