I have currently done with my code transformation on my api data by its roleId. However, I need to display another view which will group the data according to which projectId the users are in.
I can simply copy and paste and create another one for projectIds data transformation, however, I feel that my approach may be messy and not easily reusable. So I would like to ask if there is a better way to do this?
Because i cannot simply swap roleIds in the function to projectIds by putting rolesId or projectIds in a variable to be reused in the function.
Can anyone help me please ?
Code for the api data transformation to dislay in ant design tree data table:
let apiData = [
{
email: "[email protected]",
permissionIds: null,
roleIds: ["raa", "baa", "caa"],
projectIds: ["1aa", "3aa"]
},
{
email: "[email protected]",
permissionIds: null,
roleIds: ["baa", "caa"],
projectIds: ["1aa", "2aa", "3aa"]
},
{
email: "[email protected]",
permissionIds: null,
roleIds: ["caa"],
projectIds: ["1aa"]
},
{
email: "[email protected]",
permissionIds: null,
roleIds: [],
projectIds: []
}
];
//Isolate and transform data by roleId
const transData = apiData.reduce((arr, item) => {
let formatted = item.roleIds.map((id) => {
return {
roleIds: id,
children: [{ ...item, roleIds: id }]
};
});
return [...arr, ...formatted];
}, []);
//Group transformed data by roleIds
const findMatch = (arr, roleIds) =>
arr.find((item) => item.roleIds === roleIds);
const groupArray = (originalArr) => {
return Array.isArray(originalArr)
? originalArr.reduce((previousObj, obj) => {
if (findMatch(previousObj, obj.roleIds)) {
findMatch(previousObj, obj.roleIds).children.push(...obj.children);
} else {
previousObj.push(obj);
}
return previousObj;
}, [])
: "Need an array";
};
//Call the group roleId function on transformed data by roleId
const userRoledata = groupArray(transData);
//Add key to parent and children
let key = 1;
userRoledata.forEach((item) => {
item.key = key++;
item.children.forEach((child) => {
child.key = key++;
});
});
setData(userRoledata); //this will be dataSource for table rendering in ant design
What will the data transformed display when used as dataSource in ant design:
If grouped by roleIds:
[
{
"roleIds": "raa",
"children": [
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": "raa",
"projectIds": [
"1aa",
"3aa"
],
"key": 2
}
],
"key": 1
},
{
"roleIds": "baa",
"children": [
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": "baa",
"projectIds": [
"1aa",
"3aa"
],
"key": 4
},
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": "baa",
"projectIds": [
"1aa",
"2aa",
"3aa"
],
"key": 5
}
],
"key": 3
},
{
"roleIds": "caa",
"children": [
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": "caa",
"projectIds": [
"1aa",
"3aa"
],
"key": 7
},
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": "caa",
"projectIds": [
"1aa",
"2aa",
"3aa"
],
"key": 8
},
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": "caa",
"projectIds": [
"1aa"
],
"key": 9
}
],
"key": 6
}
]
If grouped by projectIds:
[
{
"projectIds": "1aa",
"children": [
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": [
"raa",
"baa",
"caa"
],
"projectIds": "1aa",
"key": 2
},
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": [
"baa",
"caa"
],
"projectIds": "1aa",
"key": 3
},
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": [
"caa"
],
"projectIds": "1aa",
"key": 4
}
],
"key": 1
},
{
"projectIds": "3aa",
"children": [
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": [
"raa",
"baa",
"caa"
],
"projectIds": "3aa",
"key": 6
},
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": [
"baa",
"caa"
],
"projectIds": "3aa",
"key": 7
}
],
"key": 5
},
{
"projectIds": "2aa",
"children": [
{
"email": "[email protected]",
"permissionIds": null,
"roleIds": [
"baa",
"caa"
],
"projectIds": "2aa",
"key": 9
}
],
"key": 8
}
]
Define a
transformfunction with 2 parameter. First theapiData, which is the data you want to transform and secondly thetransformation_keywhich is a string of eitherroleIdsorprojectIds.Within this function you first to generate an object with the different roleIds/projectIds as keys and for each key an array of all the items included.
To do so you make use of a reducer and loop over the items
Within each item we also have to loop over all the items in the roleIds/projectIds of that item, so we add a second/inner reducer.
This will generate an object like
next we map the ids to the required output
To summarize