React JS / ANTD: Create new object entries from exisiting object array - javascript

I am currently working with ANTD and React v18.
I want to display my data inside the table. For this, I need to create objects with regarding index and values.
The logic for a table is like this:
const dataSource = [
{
key: '1',
name: 'Mike',
age: 32,
address: '10 Downing Street',
},
];
const columns = [
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
{
title: 'Address',
dataIndex: 'address',
key: 'address',
},
];
<Table dataSource={dataSource} columns={columns} />;
Now I have an object array like this:
const personData = [
{
"_id": "C84113",
"Firstname": "Hola",
"Lastname": "Tester",
"__typename": "Person"
},
{
"_id": "C_C84113_0",
"Firstname": "Hermanoi",
"Lastname": "Oko",
"__typename": "Person"
}
]
How can I map or push these values, that I receive something like this ?
//we create the respective columns
const personTableColumn = [
{ title: 'Person (Teilakte)', dataIndex: 'personName' },
{ title: 'ID', dataIndex: 'personID' },
];
//I want to have it like this
//personData.foreach() or push()
{
"key":"i",
"personName":"Person.Firstname +" "+ Person.Lastname",
"personID":"Person.ID>"
}

You can iterate over the array and use the map function to create a new array with the object you need.
const personDataSource = personData.map((person, i) => {
return {
key: i,
personName: person.Firstname + " " + person.Lastname,
personID: person._id
};
});
The personDataSource will have JSON object:
[
{ key: 0, personName: "Hola Tester", personID: "C84113" },
{ key: 1, personName: "Hermanoi Oko", personID: "C_C84113_0" }
]

Related

Mapping array in javacript app in a react app

This is my array, I'm working on react app
const categoryObj = [
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Women",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
}
]
how can I access "women" in this array ? (I have many items like "women" this is just a sample of a large array. if you can suggest a mapping method it's better.)
You can map through it to get the name value in this way:
categoryObj.map((category) => category.name)
const categoryObj = [
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Women",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
},
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Men",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
},
{
id: "463e989a-c4f2-4616-85c5-0cb610c5fff0",
name: "Children",
subCategory: [
{
id: "91ba7308-b68e-4d0c-85d8-0cc8272c6bc8",
name: "All",
icon: "AllIcon"
},
{
id: "0e0712c5-0b5a-4d4e-acf5-3d7faf2caa2a",
name: "Clothes",
icon: "ClothesIcon",
sections: [
{
id: "9b7a7a58-04a1-4aba-ba68-0e6b1390021e",
name: "All",
href: "Women/Clothes/All".split(' ').join('-').trim().toLowerCase()
}
]
}
]
}
]
const result = categoryObj.filter(obj => obj.name === 'Women')
console.log('multi objects :', result)
// if unique with name
const resultUnique = categoryObj.find(obj => obj.name === 'Women')
console.log('unique object :', resultUnique)
This object contains an object and have another variations as sub. If you want to access first name,
categoryObj.map((it) => {
//You can handle it like this
console.log(it.name)
})
But if you want all name of all subCategory,
categoryObj[0].subCategory.map((cat) => {
//You can handle it like this
console.log(cat.name)
})
You have same object-type in and out.
const res = categoryObj.filter(item=>item.name === 'Women');

Antd Tree, : how to Disable checking child by default

I working on a react project using Antd and I want to be able to disable cheking childs of my Tree component, so I can check only parent.This is my code
I found that I can add checkable : false to my child but I must create a function that render me a new TreeData that I can use instead of my normal data so I've tried this :
const TreeData = (data) => {
data.map((category) => {
category.children.map((family) => {
family.children.map((table) => {
table.checkable = false;
});
});
});
};
But it return undefined when i'm console.log the data received..
So my question is : how to switch from this :
const treeData = [
{
title: "0-0",
key: "0-0",
children: [
{
title: "0-0-0",
key: "0-0-0",
children: [
{
title: "0-0-0-0",
key: "0-0-0-0"
},
{
title: "0-0-0-1",
key: "0-0-0-1"
},
{
title: "0-0-0-2",
key: "0-0-0-2"
}
]
},
{
title: "0-0-1",
key: "0-0-1",
children: [
{
title: "0-0-1-0",
key: "0-0-1-0"
},
{
title: "0-0-1-1",
key: "0-0-1-1"
},
{
title: "0-0-1-2",
key: "0-0-1-2"
}
]
},
{
title: "0-0-2",
key: "0-0-2"
}
]
},
{
title: "0-1",
key: "0-1",
children: [
{
title: "0-1-0-0",
key: "0-1-0-0"
},
{
title: "0-1-0-1",
key: "0-1-0-1"
},
{
title: "0-1-0-2",
key: "0-1-0-2"
}
]
},
{
title: "0-2",
key: "0-2"
}
];
To this :
const treeData = [
{
title: "0-0",
key: "0-0",
children: [
{
checkable: false,
title: "0-0-0",
key: "0-0-0",
children: [
{
title: "0-0-0-0",
key: "0-0-0-0"
},
{
title: "0-0-0-1",
key: "0-0-0-1"
},
{
title: "0-0-0-2",
key: "0-0-0-2"
}
]
},
{
checkable: false,
title: "0-0-1",
key: "0-0-1",
children: [
{
title: "0-0-1-0",
key: "0-0-1-0"
},
{
title: "0-0-1-1",
key: "0-0-1-1"
},
{
title: "0-0-1-2",
key: "0-0-1-2"
}
]
},
{
checkable: false,
title: "0-0-2",
key: "0-0-2"
}
]
},
{
title: "0-1",
key: "0-1",
children: [
{
checkable: false,
title: "0-1-0-0",
key: "0-1-0-0"
},
{
checkable: false,
title: "0-1-0-1",
key: "0-1-0-1"
},
{
checkable: false,
title: "0-1-0-2",
key: "0-1-0-2"
}
]
},
{
title: "0-2",
key: "0-2"
}
];
Without hardchanging the first data of my Tree.
Thank you
This may be one possible implementation to set checkable as false for the specific nodes described in this question:
const makeUnCheckable = dataArr => (
dataArr.map(
obj => ({
...obj,
children: obj?.children?.map(cObj => ({
...cObj,
checkable: false
}))
})
)
);
return (
<Tree
checkable
onExpand={onExpand}
expandedKeys={expandedKeys}
autoExpandParent={autoExpandParent}
onCheck={onCheck}
checkedKeys={checkedKeys}
onSelect={onSelect}
selectedKeys={selectedKeys}
treeData={makeUnCheckable(treeData)}
/>
);
This is the result displayed on Codesandbox:
NOTES:
The elements showing as checked are clicked manually.
There is no check option for nodes 0-0-0, 0-0-1, 0-0-2, 0-1-0-0, 0-1-0-1, 0-1-0-2 - which is the expected objective defined in the question under To this
EDITED:
On perusing this previous question it seems like OP requires something like this:
(A tree where leaf nodes are uncheckable)
This may be achieved by a recursive method - something like this:
(Changes are present in: Lines 100 to 106. And line 118.)
EDITED - 2
Update based on comments below.
In order to identify the children for any given parent/key, something like the below may be useful:
Two methods are here. One is findKey which is recursive and gets the object which has a particular key (say 0-0-1). The other is to check if the object with the key has any children and if yes, return the children array.

Flatten a deeply nested array with objects and arrays

I have an array of objects that contain another array with objects. The nesting is four levels deep.
The structure of the array is:
[
{
title: 'Title',
type: 'section',
links: [
{
label: 'Label',
id: 'id_1',
links: [
{
title: 'Title',
type: 'section',
links: [
{
label: 'Label',
id: 'id_2',
links: [
{
label: 'Label',
id: 'id_3',
links: [],
}
]
}
]
},
{
title: 'Other title',
type: 'section',
links: [
{
label: 'Label',
id: 'id_4',
links: [],
}
]
}
]
}
]
}
]
I want to have a flattened array with the id's of the link arrays that contain links (they are parents of submenu's).
So the desired outcome is like:
["id_1", "id_2"]
I have tried to get the outcome with this function taken from MDN:
flatDeep(arr, d = 1) {
return d > 0
? arr.reduce((acc, val) =>
acc.concat(Array.isArray(val.links)
? this.flatDeep(val.links, d - 1)
: val.links), [])
: arr.slice();
}
This gives me an empty array.
Use Array.flatMap(). Destructure each object and use an empty array as default for missing id values. Concat the id and the result of flattening the links recursively.
const flattenIds = arr => arr.flatMap(({ id = [], links }) =>
[].concat(id, flattenIds(links))
);
const data = [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_1', links: [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_2', links: [{ label: 'Label', id: 'id_3', links: [] }] }] }, { title: 'Other title', type: 'section', links: [{ label: 'Label', id: 'id_4', links: [] }] }] }] }];
const result = flattenIds(data);
console.log(result);
You could get a flat array with a recursion and a check for id for missing property.
const
getId = ({ id, links }) => [
...(id === undefined ? [] : [id]),
...links.flatMap(getId)
],
data = [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_1', links: [{ title: 'Title', type: 'section', links: [{ label: 'Label', id: 'id_2', links: [{ label: 'Label', id: 'id_3', links: [] }] }] }, { title: 'Other title', type: 'section', links: [{ label: 'Label', id: 'id_4', links: [] }] }] }] }],
result = data.flatMap(getId);
console.log(result);
Here is a non-recursive version.
const data = [{title:'Title',type:'section',links:[{label:'Label',id:'id_1',links:[{title:'Title',type:'section',links:[{label:'Label',id:'id_2',links:[{label:'Label',id:'id_3',links:[]}]}]},{title:'Other title',type:'section',links:[{label:'Label',id:'id_4',links:[]}]}]}]}];
const stack = data.slice();
const result = [];
let obj;
while (obj = stack.shift()) {
if ("id" in obj && obj.links.length > 0) result.push(obj.id);
stack.push(...obj.links);
}
console.log(result);
This uses breath first, but can easily be changed into depth first. You'll only have to change the stack.push call into stack.unshift.
For a more detailed explanation about the two, check out Breadth First Vs Depth First.
var array = JSON.parse('[{"title":"Title","type":"section","links":[{"label":"Label","id":"id_1","links":[{"title":"Title","type":"section","links":[{"label":"Label","id":"id_2","links":[{"label":"Label","id":"id_3","links":[]}]}]},{"title":"Other title","type":"section","links":[{"label":"Label","id":"id_4","links":[]}]}]}]}]');
arr = [];
while(array.length != 0) {
var ob1 = array.splice(0,1)[0];
for(var ob2 of ob1.links) {
if (ob2.links.length !== 0) {
arr.push(ob2.id);
array = array.concat(ob2.links);
}
}
}
console.log(arr);
Here's the output as you requested:
[
"id_1",
"id_2"
]
I think recursive function will simplify. (recursively look for lists array and push the id into res).
const data = [
{
title: "Title",
type: "section",
links: [
{
label: "Label",
id: "id_1",
links: [
{
title: "Title",
type: "section",
links: [
{
label: "Label",
id: "id_2",
links: [
{
label: "Label",
id: "id_3",
links: []
}
]
}
]
},
{
title: "Other title",
type: "section",
links: [
{
label: "Label",
id: "id_4",
links: []
}
]
}
]
}
]
}
];
const res = [];
const ids = data => {
data.forEach(item => {
if ("id" in item) {
res.push(item.id);
}
if (item.links) {
ids(item.links);
}
});
};
ids(data);
console.log(res);

How to get and link nested value to field passing columns to Material Table

I'm trying to create a table and I have nested data like this:
[{
id: 24,
name: "DANIEL TSUTOMU OBARA",
number: "134",
phone: "11111111111",
rg: "4034092666",
EmployeeStatus: {
createdAt: "2019-08-07T14:38:52.576Z"
description: "Documentos rejeitados"
id: 3
updatedAt: "2019-08-07T14:38:52.576Z"
},
Sector: {
id: 2,
name: "Controladoria"
}
}]
And have this structure columns table:
columns: [
{ title: "Nome", field: "name" },
{ title: "CPF", field: "cpf" },
{ title: "Função", field: "FunctionId", lookup: {} },
{
title: "Setor",
field: "SectorId",
lookup: {}
},
{
title: "Status",
field: "EmployeeStatus", <------- I want to get description here
editable: "never"
}
],
Then, I need to pass these columns into my Material-table like this:
<MaterialTable
columns={state.columns}
data={state.data}
title=""
icons={tableIcons}
editable={{
onRowAdd: newData => createInstructor(newData),
onRowUpdate: async (newData, oldData) =>
updateInstructor(newData, oldData),
onRowDelete: oldData => deleteInstructor(oldData)
}}
/>
So, how I can do that access nested data into column field?
Thanks!
Please find the below solution.
I am expecting the data to have other objects too, so finding the first object with the key available.
let data = [{
id: 24,
name: "DANIEL TSUTOMU OBARA",
number: "134",
phone: "11111111111",
rg: "4034092666",
EmployeeStatus: {
createdAt: "2019-08-07T14:38:52.576Z",
description: "Documentos rejeitados",
id: 3,
updatedAt: "2019-08-07T14:38:52.576Z"
},
Sector: {
id: 2,
name: "Controladoria"
}
}]
let columns = [
{ title: "Nome", field: "name" },
{ title: "CPF", field: "cpf" },
{ title: "Função", field: "FunctionId", lookup: {} },
{
title: "Setor",
field: "SectorId",
lookup: {}
},
{
title: "Status",
field: "EmployeeStatus",
editable: "never"
}
];
let columnToUpdate = columns.find(obj => obj.title==="Status"); //find the column in columns array
let desc = data.find(obj => Object.keys(obj).includes('EmployeeStatus')).EmployeeStatus.description; // get description
columnToUpdate.field = desc; // mutate the object
console.log(columns);
I just decided to use lookup functionality and solve in this way for now.
const [state, setState] = useState({
columns: [
{ title: "ID", field: "id", editable: "never" },
{ title: "Nome", field: "name" },
{ title: "CPF", field: "cpf" },
{ title: "Função", field: "FunctionId", lookup: {} }, // 3
{
title: "Setor",
field: "SectorId",
lookup: {}
}, // 4
{
title: "Status",
field: "EmployeeStatusId",
lookup: {},
editable: "never"
}, // 5
]});
....
await api
.get(`/employee-status`)
.then(result => {
status = formatSectors(state, result, 5);
})
.....
const formatSectors = (state, result, position) => {
let columns = state.columns;
const indexColumnSector = 4;
columns[position].lookup = result.data.rows.reduce(
(accumulator, currentValue) => {
accumulator[currentValue.id] =
position === indexColumnSector
? currentValue.name
: currentValue.description;
return accumulator;
},
{}
);
return columns;
};

Assign array values to an item in object - Javascript/React

I have an object with few items and I want to update the values of one property from array.
Object :
structure = [
{
id: 'name',
label: 'Name',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'address',
label: 'Address',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'phone',
label: 'Phone',
filterType: 'select',
filterOn: 'contains',
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
if the id is phone then I want to get the values from the array and assign it to the options instead of hard coding it.
In this object of id phone:
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
array is coming from
this.props.phoneList
label and values will be this.props.phoneList[i].name
how to loop over this and get the latest values from the array
This should keep the order of the array intact also:
const newStructure = structure.map(item => {
const isPhone = item.id === “phone”
return {
...item,
options: isPhone ? this.props.phoneList : (item.options || undefined)
}
}

Categories

Resources