gregnb / gregnb/mui-datatables

customBodyRender a cell with multiple links from an array

Open
#1,891 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
JavaScript
Stars
2.7k
Forks
906
PR merge metrics
No merged PRs in 30d

Description

Hello!

This isn't a bug but me trying to figure out how to do something, if it's possible.

I am creating an app with a lot of relationships and I want to create links to different profiles within the cells. Sometimes a single cell may need to contain more than one link.

An example of this use case might be Pet owners and their pets. Say I create a table of Owners and then in one cell is a list of the pet names

| Owners | Pet Names |
|---------------|-------------|
| Paige | Sally, Sage, Ember |

I've gotten it to where I can push all the names of the animals related to a specific owner to a new array and then join that array to create a string that shows up properly with all the pets listed. When I click on the row I get taken to the owner profile with the onRowClick function which is exactly how I want it

Code Example
```
const [data, setData] = useState([]);
const [petColumns, setPetColumns] = useState([]);
const [columnData, setColumnData] = useState([]);
const [options, setOptions] = useState({
filter: true,
filterType: 'dropdown',
responsive: 'standard',
rowsPerPage: 10,
resizableColumns: true,
enableNestedDataAccess: '.',
selectableRows: 'none',
onRowClick: (rowData) => {
handleClick(rowData);
}
})

setPetColumns = [
{
name: "id",
label: "Id",
options: {
display: 'excluded',
}
},
{
name: "name",
label: "Owner Name",
},
{
name: "pet",
label: "Pets",
},
]

useEffect(() => {
API.getOwnerData(ownerId)
.then(res => setData(res.data))
.catch(err => console.log(err))
}, [ownerId])

useEffect(() => {
const ownerData = data.map((owner) => {
const petList = []
owner.Pets.forEach((pet) => {
petList.push({
name: pet.name,
})
})

const petObject = {
id: owner.id,
name: `${owner.User.firstName} ${owner.User.lastName}`,
pet: petList.map(p => p.name).join(', '),
}
return petObject
})
setColumnData(ownerData)
}, [data])

const handleClick = (rowData) => {
navigate(`${rowData[0]}`)
}

```

Where I'm running into trouble is that I want to turn each of the pet names that are being listed into a link that will navigate to the pets respective profile when clicked on. I will show some of my attempts to do this and explain what the results were.

ATTEMPT 1

Here I added pet.id to the petList object. This id is used with react-router-dom and Link to travel to the proper profile page for the pet. I then set up a customBodyRender (I tried both customBodyRender and customBodyRenderLite) which is supposed to map through the pet list and create a link with the pet name for each entry and then join together the new link divs.

I'm actually fairly stumped on this because I keep getting "Uncaught TypeError: value.map is not a function". Which makes me think that the value of property is not being recognized as an array. However, I found several StackOverFlow posts where value is treated properly as an array and can be joined together such as [here](https://stackoverflow.com/questions/58581404/how-do-i-render-an-array-of-items-inside-column-using-mui-data-tables).

I also recognize though that the array in that stack overflow is flat which mine is not but I even added the "enableNestedDataAccess: '.'," to that specific set of options (even though it's already in the general options for the table) just to make sure. I tried some variations of metadata as well but couldn't get that to stick either, I honestly think I'm probably incorporating it wrong.

CODE EXAMPLE - **I didn't include the code that remained unchanged**
```
setPetColumns = [
{
name: "id",
label: "Id",
options: {
display: 'excluded',
}
},
{
name: "name",
label: "Owner Name",
},
{
name: "pet",
label: "Pets",
options: {
customBodyRenderLite: (value) => { ****ATTEMPTED customBodyRender TO RENDER THE LINK AND THEN JOIN ****
return (
<>
{value.map((e) => {
{e.name}
}).join(', ')}

)
}
}
},
]

useEffect(() => {
const ownerData = data.map((owner) => {
const petList = []
owner.Pets.forEach((pet) => {
petList.push({
name: pet.name,
id: pet.id ****ID IS ADDED FOR NAVIGATION PURPOSES****
})
})

const petObject = {
id: owner.id,
name: `${owner.User.firstName} ${owner.User.lastName}`,
pet: petList
}
return petObject
})
setColumnData(ownerData)
}, [data])

```

When I console log columnData I get exactly what I'm expecting
DATA EXAMPLE
```
0:
id: "30c9"
name: "Paige"
property: Array(3)
0:
id: "df43"
name: "Sally"
1:
id: "dea4"
name: "Sage"
2:
id: "ger7"
name: "Ember"
```

ATTEMPT 2

My attempt here was kind of a hail mary, I'd been working trying to get the custom render to work for a long while so I thought I'd go at it from a different direction. I trying to include Link within the petObject that initially worked in providing the plain joined names.

My result of this attempt was that my data table rendered but I got [ object Object ] within the pet Columns if I included return in the .map function or an empty string if there was no return. I honestly didn't really expect this to work but was at a loss of what else to try. When I consoled the columnData it was either [ object Object ] or ""

```
setPetColumns = [
{
name: "id",
label: "Id",
options: {
display: 'excluded',
}
},
{
name: "name",
label: "Owner Name",
},
{
name: "pet",
label: "Pets",
},
]

useEffect(() => {
const ownerData = data.map((owner) => {
const petList = []
owner.Pets.forEach((pet) => {
petList.push({
name: pet.name,
id: pet.id ****ID IS ADDED FOR NAVIGATION PURPOSES****
})
})

const petObject = {
id: owner.id,
name: `${owner.User.firstName} ${owner.User.lastName}`,
*****TRIED TO INCLUDE LINK WITHIN OBJECT****
pet: petList.map((p) => {
return p.name ****If return isn't included a blank string is returned****
}).join(', '),
}
return petObject
})
setColumnData(ownerData)
}, [data])

```

RESULT
| Owners | Pet Names |
|---------------|-------------|
| Paige | [object Object] |

| Tech | Version |
|--------------|---------|
| Material-UI | 4.12.3 |
| MUI-datatables | 4.1.2 |
| React | 17.0.2 |
| browser | Google Chrome |

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.