How do I render nested JSON data on react material UI data grid. In the sandbox attached I want to show the phone numbers of the users from the json on the data grid-Nested JSON Data Grid
Asked
Active
Viewed 2.8k times
15
-
Hi, welcome to StackOverflow. Please review [ask] and provide a [mcve] when asking a question. – admcfajn Jan 06 '21 at 08:37
-
Why not flatten your json object? – Janice Zhong Jan 06 '21 at 08:41
-
Hi I have added the sandbox url in the question @admcfajn – Learner Forever Jan 06 '21 at 08:42
-
@JaniceZhong, this is just a sample of what I am trying to achieve...the real data is more complex – Learner Forever Jan 06 '21 at 08:43
-
Yes @LearnerForever but it would be easier for everyone to collaborate on if you create a snippet here :) – admcfajn Jan 06 '21 at 08:49
-
@admcfajn here's the snippet https://codesandbox.io/s/material-demo-forked-2sc7v – Learner Forever Jan 06 '21 at 08:55
-
You could just re-arrange your json data structure, here's an example: https://codesandbox.io/s/material-demo-forked-3xcjn – Rasmus Puls Jan 06 '21 at 09:48
5 Answers
23
I use this in my project :
{
field: 'idMaintenancePlan',
headerName: 'Plan de maintenance',
sortable: false, width: 200,
valueGetter: (params) => params.row?.maintenancePlan?.name
}
-
3
-
2
-
2Take into account that the value that we get from `valueFormatter` is not used for filtering and sorting so in the majority of cases using `valueGetter` will be a better solution. From [MUI Data-grid documentation](https://mui.com/x/react-data-grid/column-definition/#value-formatter): The value generated is only used for rendering purposes. Filtering and sorting do not rely on the formatted value. Use the valueParser to support filtering. – Ariel Gerstein Aug 01 '22 at 18:20
-
1For current version, it's like following: `valueGetter: (params) => params.row?.jobType?.name` – Rafi Mahmud Mar 25 '23 at 03:24
18
To solve the problem, let's see params
object passed in valueGetter
function. Log that and you will find a row
object under it. Instead of using params.getValue()
, you should access the row
object. It seems that params.getValue()
can only be used on one-level JSON object. Here is the code snippet to output phone
field.
{
field: "phone",
headerName: "Phone",
width: 160,
valueGetter: (params) => {
console.log({ params });
let result = [];
if (params.row.phone) {
if (params.row.phone.home) {
result.push("home: " + params.row.phone.home);
}
if (params.row.phone.office) {
result.push("office: " + params.row.phone.office);
}
} else {
result = ["Unknown"];
}
return result.join(", ");
}
}
Update
To have more flexibility on checking if every key under a object exists, I have created a helper method:
const checkKeysUnderObject = (obj, result) => {
for (let key in obj) {
if (key) { // push the value to the result array only if key exists
result.push(key + ": " + obj[key]);
}
}
};
usage of the helper method:
if (params.row.phone) {
checkKeysUnderObject(params.row.phone, result);
}else{
result = ["Unknown"];
}
I have also updated the codesandbox here.

Janice Zhong
- 836
- 7
- 16
-
1The sandbox is returning errors... No row with id #firstName found – Adam Youngers Oct 13 '21 at 00:35
-
I worked around the error using this: valueGetter: params => `${params?.params?.row?.firstName || ""} ${params?.params?.row?.lastName || ""}` – Adam Youngers Oct 13 '21 at 00:47
-
Also, are we saying that sorting is not an option for nested object responses? I'm currently on the fence as to this approach or passing API response through a method to flatten it so `,phone:{home:"11", office:"22" }` would become `,phone_home:"11", phone_office:"22"` – Adam Youngers Oct 13 '21 at 00:58
8
this works fine for me
{ field: 'parserInfo', headerName: 'Parser Title', valueFormatter: ({ value }) => value.title }

Manish Rawat
- 1,142
- 1
- 18
- 34
6
this works fine also
{
field: "family",
headerName: "Family",
width: 150,
renderCell: (params) => {
return <div className="rowitem">{params.row.family.name}</div>;
},
},

saberbouagila
- 69
- 1
- 1
-
suggestion : you can use code fences instead of snippets since the snippet feature here is not necessary, also add a language identifier to highlight the code based on the language and make it more readable – I_love_vegetables Jul 14 '21 at 08:45
0
This one worked for me:
const columns = [
{
field: "post",
headerName: "TITLE",
valueFormatter: (post: any) => post.value.title
}
]
In my case post
is a property of the tutorial
entity.
<DataGrid
rows={tutorials}
columns={columns}
slots={{
toolbar: GridToolbar,
}}
/>
The Tutorial
entity
export interface Tutorial {
id: number;
...
post: Post;
}
... and the Post
entity.
export interface Post {
id: number;
title: string;
...
}

PeterPazmandi
- 533
- 10
- 13