I have columns as:
const columns = React.useMemo(
() => [
{
Header: "Name",
accessor: "name", // accessor is the "key" in the data
},
{
Header: "Email",
accessor: "email",
}
])
and my table code snippet looks like:
<table
{...getTableProps()}
id="basicTable"
className="table table-bordered action-table table-striped table-hover mb-0"
>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th
{...column.getHeaderProps()}
className="align-top"
>
<div
// {...column.getSortByToggleProps()}
onClick={(e) => {
console.log(
`col ${column.accessor}`
);
}}
>
{column.render("Header")}
</div>
<div>
{column.canFilter
? column.render(
"Filter"
)
: ""}
</div>
</th>
))}
</tr>
))}
</thead>
</table>
Now, here on th, I am trying to retrive the accessor, but I am not being able to do so, on consoling, column.accessor, it returns:
function accessor(row) {
return getBy(row, accessorPath);
}
How, could I get the accessor name so that I could fire api call with col name for sorting?
Update:
accessor function looks as:
Keeping accessor as function helps in handling few other functionalities, for this usecase try to keep another key(eg. sortByBE) for that in column configuration.
Try console.log(cell.value) , you will get the associated cell value.
Related
I have an object:
{
cities: {
MCR: "Manchester",
LDN: "London",
NYC: "New York"
}
}
and I want to iterate over these and display them in a table format which will show the city code and the long name next to it. Something like:
<tbody>
<tr>
<th>City Code</th>
<th>City Name</th>
</tr>
<tr>
{Object.entries(cities).map(([key, value]) => {
<>
<td>{key}</td>
<td>{value}</td>
</>
}
)}
</tr>
</tbody>
However this doesn't display anything and also shows an error when hovering over value:
Type 'unknown' is not assignable to type 'ReactNode'.ts(2322)
I'm quite new to React and wondering how best to display this information?
Thanks
let say you have an object as:
const obj = {
cities: {
MCR: "Manchester",
LDN: "London",
NYC: "New York"
}
};
It would be better to loop over cities and create a new tr so that It looks like a table
CODESANDBOX LINK
You want to map over the cities then you should return it from map as:
<tbody>
<tr>
<th>City Code</th>
<th>City Name</th>
</tr>
{ Object.entries( obj.cities ).map( ( [key, value] ) => {
return ( // PROBLEM SHOULD RETURN
<tr>
<td>{ key }</td>
<td>{ value }</td>
</tr>
);
}
) }
</tbody>
You need to return the result in each iteration. Also, each iteration would return a tr with a key prop:
{
Object.entries(obj.cities).map(([key, value]) => (
<tr key={key}>
<td>{key}</td>
<td>{value}</td>
</tr>
))
}
Note: since city is a key in an object, you'll need to access it as above
You are just missing the return in your map's callback function. Always remember to include a return in your arrow functions when using it like this: () => {}. It is easy to miss because ()=>() would return whatever you write in the second () but in the former example this is not true.
How to input array into 1 column table ? Audience number 2 have 2 Films B & C. I want to become 1 column. ex [Film B, Film C] in Column Film.
My Table =>
The Table Image
const AudienceListComponent = () => {
const [audience, setAudience] = useState([])
console.log("audience", audience)
const getAllAudience = () => {
AudienceService.getAllAudiences().then((response) => {
console.log('response', response)
setAudience(response.data)
})
}
useEffect(() => {
getAllAudience()
}, [])
return (
<div>
<table className="table table-bordered table-bordered">
<thead className="table-dark">
<tr>
<th>No</th>
<th>Audience Name</th>
<th>Film</th>
</tr>
</thead>
<tbody>
{
audience.map((aud, i) => (
<tr key={aud.id}>
<td>{i + 1}</td>
<td>{aud.name}</td>
{aud.film.map(films =>
<td>{films.title}</td>
)}
</tr>
))
}
</tbody>
</table>
</div>
);
};
export default AudienceListComponent;
Solved by #Hamza Khan in a comment:
You need to run the map loop inside your td element like this: <td> {aud.film.map(films => films.title )} </td>
export const COLUMNS = [
{
Header : 'Total Cases',
accessor : 'totalcases',
},
{
Header : 'Active Cases',
accessor : 'activecases',
},
{
Header : 'Total Recovery',
accessor : 'recovery',
},
{
Header : 'Total Death',
accessor : 'deaths',
},
{
Header : 'New Cases',
accessor : 'newcases',
},
]
function Table({countryData}) {
const columns = useMemo(()=> COLUMNS, []);
const data = useMemo(()=> countryData, []);
const {
....
setGlobalFilter,
} = useTable({
columns,
data
}, useGlobalFilter, useSortBy);
const{globalFilter} = state;
return (
<>
<GlobalFilter filter={globalFilter} setFilter={setGlobalFilter}/>
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
</>
)
}
export default Table
here I want to sort the entire table by default on the basis of new cases column and want toggle sort only on active cases and recovery. as Im new to react i dont know how to provide custom sort..............................................................................................................................................................................................................................................................
you can use :
columns.sort((a, b) => (a.accessor > b.accessor ) ? 1 : -1) More informision at this link: https://flaviocopes.com/how-to-sort-array-of-objects-by-property-javascript/
my "calculated" column Header: 'EV/Resource ($ per oz)' when sorting does not appear to sort in any ascending or descending order when pressed in the react table, it randomize the table sort in a way. Am i doing a "calculated column" correctly ? all my other columns sort correctly.
{
Header: 'in-situ ($b)',
accessor: 'minerals_value',
Cell: (row) => {
return (row.value / 100 / 1000000000).toFixed(2)
},
},
{
Header: 'GMV ($/t)',
accessor: 'minerals_value_per_ton',
},
{
Header: 'EV/Resource ($ per oz)',
id: 'evresource',
accessor: 'evresource',
sortType: 'basic',
Cell: (row) => {
return Number(
row.row.original.company.enterprise_value /
100 /
row.row.original.primary_mineral.contained
).toFixed()
},
},
table render:
<table {...getTableProps()}>
<thead>
{headerGroups.map((headerGroup) => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map((column) => (
<th {...column.getHeaderProps(column.getSortByToggleProps())}>
{column.render('Header')}
<span>{column.isSorted ? (column.isSortedDesc ? ' ▼' : ' ▲') : ''}</span>
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map((cell) => {
return <td {...cell.getCellProps()}>{cell.render('Cell')}</td>
})}
</tr>
)
})}
</tbody>
</table>
You need to implement a custom accessor in order for the sorting to work correctly.
Specifically:
{
Header: 'EV/Resource ($ per oz)',
id: 'evresource',
accessor: customAccessor,
and
function customAccessor(row) {
return Number(
row.company.enterprise_value /
100 /
row.primary_mineral.contained
)
}
}
I am trying to render my array of objects inside my table but it shows "Cannot read property 'monthlytarget' of undefined", I am using axios to fetch the result and render inside the table
Axios :
http.get(apiReportsEndpoint+"?empid="+this.props.match.params.id)
.then(response =>{
this.setState({
report:response.data.data.monthlytarget
})
});
Response I receive from API
"data":{
"monthlytarget":[
{
"quarter":1,
"period_start":"2019-04-01",
"monthlytarget":{
"04":{
"targetpm":"213120",
"invoice_values":[
],
"revenuepm":0,
"targetpercentage":0,
"joinees":0
},
"05":{
"targetpm":"213120",
"invoice_values":[
],
"revenuepm":0,
"targetpercentage":0,
"joinees":0
}
}
},
{ quarter":2 ...},
{ quarter":3 ...},
]
}
I want to render values inside "monthlytarget" as rows inside table
<thead>
<tr>
<th>MONTH</th>
<th>TARGET PER MONTH</th>
<th>REVENUE PER MONTH</th>
</tr>
</thead>
<tbody>
{
this.state.report.map((revenuereport) =>{
{Object.keys.map.monthlytarget(premise,index) => (
<tr>
<td>{index}</td>
<td>{premise.targetpm}</td>
<td>{premise.revenuepm}</td>
</tr>
))}
})
}
</tbody>
To create one table out of all the data you could do the following:
this.state.report
.map(({ monthlytarget }) => Object.entries(monthlytarget))
.flat()
.map(([key,value], index) => (
<tr key={index}>
<td>{index}</td>
<td>{value.targetpm}</td>
<td>{value.revenuepm}</td>
</tr>
));
what do you mean by calling Object.keys.map.monthlytarget? if you are trying to loop the array and get JSX, do this:
this.state.report.map((revenuereport) =>
Object.keys(revenuereport.monthlytarget).map((premise, index) => (
<tr>
<td>{index}</td>
<td>{revenuereport.monthlytarget[premise].targetpm}</td>
<td>{revenuereport.monthlytarget[premise].revenuepm}</td>
</tr>
))
);
Do pay attention to indents and brackets, code snippet in the question seems not gonna work at all.
It should be...
this.state.report.map(({ monthlytarget }, i) =>
Object.values(monthlytarget).map({ targetpm, revenuepm }, i) =>
<tr>
<td>{i}</td>
<td>{targetpm}</td>
<td>{revenuepm}</td>
</tr>
))