Antd design table column -> how to pass array of objects to dataIndex - reactjs

I'm fetching object (contract) from DB, it contains few fields, one of them is an array of objects (products). I have antd table with column Products and I would like to fill it with product names.
For example, my contract object also has account object, and the way I use dataIndex there is like this:
{
title: 'Account',
dataIndex: ['account', 'name'],
key: 'account',
align: 'center',
sorter: (a, b) => a.length - b.length
}
That works fine! But Account is not an array.
Here is code with issue:
{
title: 'Products',
dataIndex: ['products'],
key: 'products',
align: 'center',
filters: []
}
Here is how I map data that is send to component above which has to fill table:
return data.map((contract) => ({
key: contract._id,
account: contract.account,
products: [contract.products],
}));
I tried returning just contract.products, tried returning Object.values(contract.products), tried to JSON.stringify(contract.products) but then I don't know how to parse it in column and take just name...
The only way I managed to set name was by not sending object. Example:
return data.map((contract) => ({
key: contract._id,
account: contract.account,
products: contract.products.map(product => product.name),
}));
This would indeed solve this problem, but it would made me make another asyncThunk method where I would return whole array of objects.
Hope that I described that well,this is for my college project and it's bean bugging me whole day.
I would be very grateful if someone knows how can I solve this.

According to Antd documentation for column dataIndex, it will only accept a string or an array of strings for nested paths.
dataIndex - Display field of the data record, support nest path by string array - string | string[ ]
So I don't think you can pass an array of objects to dataIndex.
The only way around that I can think of would be to convert the array to a string before passing it to your table.
To do that you can use .join() method to add space and a comma between your array items.
const convertArrayToString = (array) => array.join(', ');
And before returning you could use the above function: Example:
return data.map((contract) => ({
key: contract._id,
account: contract.account,
products: convertArrayToString(contract.products),
}));

Related

TanStack Table 8 : access nested array in data model

I'm looking for a way to access a nested array in my data structure.
My objects in my data array look like this :
{
name: name,
logo: url,
categories: [
{
name: Entertainment,
slug: "entertainment
},
{
name: Kids,
slug: kids
},
]
}
In the Docs I states that I need to use columnHelper.accessor to extract primitive values for each item in your data array.
My question is : how can I configure my accessor on "categories" to display both of them in my cell (using map I guess) ?
First, you don't need to use columnHelper; you can, for convenience (well, type safety, mostly).
You can do something like this:
cell: info => {
const value = info.getValue() as YourCategoryType[]; //casting may not be required here
return <>{value.map(v => <p key={v.slug}>{v.name}</p>)}</>
},

I am using React Table to create Table. Accessor and Cell behaving differently. Could you pls assist me with this issue

I created a React Table, to display fetched data on the Table. I use special function in accessor to display the data the way I wanted, but now I need to use the function which i have used in accessor, I need to use it in Cell, but for some reason when I use the same function in Cell, i receive different values than accessor.
Code with Accessor:
id: 'order',
Header: t('affiliateStats:table.orderNumber'),
accessor: Accessor.editButtonFormat(
orderEditModalForm,
'order.orderNumber',
{ hideWhenButtonTextBlank: true }
),
className: 'text-nowrap',
},
code with Cell:
id: 'order',
Header: t('affiliateStats:table.orderNumber'),
accessor: 'order.orderNumber',
className: 'text-nowrap',
Cell:editButtonFormatCell(
orderEditModalForm,
{ hideWhenButtonTextBlank: true}
)
},

How can I get the Material-UI DataGrid to read object data from an array?

I'm currently using Redux to fetch data from an API. I am then using this data to populate a DataGrid component from Material-UI. Below is what the api response looks like:
Below is what I currently have setup for the column definitions:
The DataGrid seems to be able to recognize the id field from the results, as seen below, however, I cannot seem to drill down into attributes to get further details.
I'm looking for a solution that will allow me to display the attribute data, along with the id. All help is appretiated, thank you!
You can use valueGetter:
const columns = [
// ...
{
field: 'attributeName',
headerName: 'Attribute Name',
valueGetter: (params) => {
return params.getValue(params.id, "attributes").name;
}
},
// ...
];
You may also need a sortComparator to handle the sorting of this column.
try something like this to map the data out obviously change around the names as needed
const detailsRows = rows.map((row) => {
return {
id: row.item_id,
model: row.model_no,
title: row.title,
};
and then pass it in to DataGrid like this
<DataGrid rows={detailsRows} columns={props.columns} pageSize={10}/>

Adding serial number column in the table

I am using a library named react-data-table-component for table in my application. Everything is going pretty smooth however I need to add a column which will show serial number in my table. The serial number will always start from 1 to total number of objects in photos array.
const columns = [
{
name: '#',
selector: 'id',
cell: (row) => <span>{I need to show serial number here}</span>
},
{
name: 'Name',
selector: 'photo_link',
sortable: true,
}
... // Other fields
]
<DataTable
columns={columns}
data={photos}
paginationTotalRows={total_photos}
Cell key inside column array just takes row as argument and it has current object but I can't get the index of object.
I have the id field in every object of the array but that is not in sequence which I need. How do I solve this problem?
I think the easiest way is to add the serial number to your array items upfront.
photos.forEach((photo, index) => { photo.serial = index + 1; });
Then, simply use this serial field in your columns definition:
{
name: '#',
selector: 'serial'
}
I know it's late, but posting as it would help others!
You can have a serial number with the help of index in your column definition, for example
const columns = [
{
name: '#',
cell: (row, index) => index + 1 //RDT provides index by default
},
... // Other fields
]
And indexes start with 0 always, so we are using + 1, Now it will start with 1.
Try this in columns
render:(text,record,index)=>`${index+1}`,
You were almost there.
I used below code to get the desired outcome, We can avoid adding new field ('serial' as suggested by Zord) to objects in the array.
Cell: (props) => (<span>{props.index + 1}</span>)

How to order data in an Ant Design V2.x table?

I am using Ant Design V2.X and I cannot update to a newer version. I inherited code and I am struggling to sort the data according to certain column. It should be ordered once, and not sorted dynamically.
This is what I have within the return() function of my React component:
<Table size="small"
dataSource={this.props.Data}
rowKey={(record) => (record.LedgerId * 100 + record.PositionId).toString()}
pagination={false}
showHeader={true}
>
I was assuming the rowKey would order my data according to the arrow-function, but this is not the case. Can you all guide me how to solve this?
Background info
Within the component, I have the following declaration:
export interface ViewTableProps {
selectedEntity: number,
Data Interfaces.ViewEntry[],
}
and elsewhere
export interface ViewEntry {
//Id: number,
LedgerId: number,
PositionId: number,
Value: number,
children: ViewEntry[]
}
Related and not-so related posts
Antd table - sort dosen't work with render
Can't sort Column in Ant Design Table in Gatsby site
Sort an antd (Ant Design) table that has selection enabled
If you want to add actual sorters to your individual columns, you'd need to write sort functions in the sorter property of your column definitions. If you want to sort the entire dataset by default, you could sort the dataSource before passing it to the table.
Column sort from their docs:
{
title: 'Age',
dataIndex: 'age',
defaultSortOrder: 'descend',
sorter: (a, b) => a.age - b.age,
},
If you want a "default sort," you can just make a function to sort data outside the table;
const sortData = (data) => {
// Call slice to create a new Array and prevent mutating it if it's stored in state
return data.slice().sort((a, b) => a.myKey - b.myKey);
}
...
<Table size="small"
dataSource={sortData(this.props.Data)}
rowKey={(record) => (record.LedgerId * 100 + record.PositionId).toString()}
pagination={false}
showHeader={true}
>
If you would like to order dates, I recommend this:
import moment from 'moment';
and add
{
title: 'Date',
dataIndex: 'date',
key: "date",
sorter: (a, b) => moment(a.date).unix() - moment(b.date).unix()
},

Resources