I have a groups API which has id and group_name field. There is another training API which gives me training_name and training_group_id.
Every training in training API is linked to a group.
Present Output on UI - Group 1 - Training 1 | Group 2 - Training 2 | Group 2 - Training 3 | Group 2 - Training 4
Is there a way I can show by grouping the trainings which has common group_name to appear under one group_name and not repeat as shown in above output?
Expected Output on UI - Group 1 - Training 1 | Group 2 - Training 2, Training 3, Training 4
Code -
function TileViewNew() {
const { currentUserTrainings, trainingGroups } = useContext(MyContext);
const renderTrainingGroupName = training => {
const trainingGroupName = trainingGroups.find(group => {
return group.id === training;
});
return trainingGroupName.group_name;
};
return (
<Grid>
{currentUserTrainings.map(({ training_name, training_group }) => (
<>
<Grid>
<strong>{renderTrainingGroupName(training_group)}</strong>
</Grid>
{training_name}
</>
))}
</Grid>
);
}
export default TileViewNew;
Maybe you need to construct a new data structure
to achieve the rendering you want
Because UI = fn(data)
I hope this helps you

import { type FC, useState, useEffect } from 'react';
const currentUserTrainings = [
{
training_name: 'Training 1',
training_group: 1,
},
{
training_name: 'Training 2',
training_group: 2,
},
{
training_name: 'Training 3',
training_group: 2,
},
{
training_name: 'Training 4',
training_group: 2,
},
];
const trainingGroups = [
{
group_name: 'Group 1',
group_id: 1,
},
{
group_name: 'Group 2',
group_id: 2,
},
];
export const TileViewNew: FC = () => {
const [result, setResult] = useState({});
useEffect(() => {
const targetDate = currentUserTrainings.map((item) => {
const group = trainingGroups.find((group) => group.group_id === item.training_group);
return {
...item,
group_name: group.group_name,
};
});
const targetResult = {};
targetDate.forEach((item) => {
targetResult[item.group_name] = targetResult[item.group_name] || [];
targetResult[item.group_name].push(item);
});
// console.log(targetResult);
setResult(targetResult);
}, []);
return (
<>
{Object.keys(result).map((k) => (
<div key={k}>
<b>{k}</b>
{result[k].map((c) => (
<span key={c.training_name}>{c.training_name}</span>
))}
</div>
))}
</>
);
};
export default TileViewNew;
You can basically transform the data you get from api in this fashion
const currentUserTrainings = [{training_name: 'Training 1',training_group_id: 1,},{training_name: 'Training 2',training_group_id: 2,},{training_name: 'Training 3',training_group_id: 2,},{training_name: 'Training 4',training_group_id: 2,},];
const trainingGroups = [{group_name: 'Group 1',group_id: 1,},{group_name: 'Group 2',group_id: 2,},];
// group trainings by group id
let transformedTraining = currentUserTrainings.reduce((acc,curr) => {
let id = curr.training_group_id
acc[id] = acc[id] || []
acc[id].push(curr)
return acc
}, {})
// loop over groups to show final output
trainingGroups.forEach((curr)=>{
let name = curr.group_name
let id = curr.group_id
let trainings = transformedTraining[id]?.map(v => v.training_name).join(',')
console.log(name, trainings)
})