Reputation: 85
I have a response json like this:
[
{
"DESCRIPTION": "OER",
"OER_HI": 23.23650286618332,
"OER_BI": 23.419567144988942,
"OER_SBI": 23.74404977161088
},
{
"DESCRIPTION": "CPO Production",
"OER_HI": 1046.17,
"OER_BI": 10538.517,
"OER_SBI": 87788.887
},
{
"DESCRIPTION": "CPO Dispatch",
"OER_HI": 1489.6000000000001,
"OER_BI": 9145.67,
"OER_SBI": 81187.22
},
{
"DESCRIPTION": "CPO Stock",
"OER_HI": 12032.43,
"OER_BI": null,
"OER_SBI": null
},
{
"DESCRIPTION": "Total Oil, Losses/FFB",
"OER_HI": 1.4761952,
"OER_BI": 1.4469707631313098,
"OER_SBI": 1.44239404903668
}
]
And I want to map it so it will fill the table header with the json keys and rows with the json values like this:
This screenshot is how it is supposed to look, so I mapped it using this code:
import React, {useEffect} from "react";
import {connect, useDispatch} from "react-redux";
import {Table, Header} from "semantic-ui-react";
import {fetchChart8} from "../redux/actions";
import LoadingStatus from "./templates/LoadingStatus";
import _ from "lodash"
const TableChart = ({chart_8}) => {
const dispatch = useDispatch();
let testMap = chart_8?.map(data => {
return Object.keys(data)
})
let description = testMap[0]
let oer_hi = testMap[0]
let oer_bi = testMap[0]
let oer_sbi = testMap[0]
useEffect(() => {
dispatch(fetchChart8())
}, [dispatch]);
if (_.isNull(chart_8)) return <LoadingStatus/>;
return (
<div>
<Header>
<Header.Content>CPO</Header.Content>
</Header>
<Table celled>
<Table.Header>
<Table.Row>
<Table.HeaderCell>
{description}
</Table.HeaderCell>
<Table.HeaderCell>
{oer_hi}
</Table.HeaderCell>
<Table.HeaderCell>
{oer_bi}
</Table.HeaderCell>
<Table.HeaderCell>
{oer_sbi}
</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body>
{chart_8.map((data) => {
return (
<Table.Row>
<Table.Cell>
{data["DESCRIPTION"]}
</Table.Cell>
<Table.Cell>
{data["OER_HI"]}
</Table.Cell>
<Table.Cell>
{data["OER_BI"]}
</Table.Cell>
<Table.Cell>
{data["OER_SBI"]}
</Table.Cell>
</Table.Row>
)
})}
</Table.Body>
</Table>
</div>
);
};
const mapStateToProps = (state) => {
return {
chart_8: state.dashboard.chart_8
};
};
export default connect(mapStateToProps, { fetchChart8 })(TableChart);
Instead I got a table like this, with table headers filled with duplicate values of json keys. What did I do wrong in the code shown?
Upvotes: 0
Views: 1117
Reputation: 29
In your Solution,
let testMap = chart_8?.map(data => {
return Object.keys(data)
})
map will return all the keys in every iteration hence your testMap will have 4 elements with all the same keys and also you are accessing them with same index i.e,
let description = testMap[0]
let oer_hi = testMap[0]
let oer_bi = testMap[0]
let oer_sbi = testMap[0]
Hence testMap[0] will have all keys i.e ['description','oer_hi','oer_bi','oer_sbi'],
If you want to fix the error with your own approach above, you will have to use,
let description = testMap[0][0]
let oer_hi = testMap[0][1]
let oer_bi = testMap[0][2]
let oer_sbi = testMap[0][3]
or else if your keys has static length you can map the keys in correct way like,
let testMap = Object.keys(chart_8[0])
Upvotes: 0
Reputation: 102247
The better way is not to use Object.keys()
, because it does not guarantee the order of the key array is stable. The table head columns are enumerable, We should declare the array of table headers in a determined order. And later, find the value of the table cell in each row by the table head columns. So that we can ensure that each table head and table cell data are corresponding.
TableChart.tsx
:
import * as React from 'react';
import { Table, Header } from 'semantic-ui-react';
export const TableChart = ({ chart_8 }) => {
// const tableHeaders = Object.keys(chart_8?.[0] || {});
// Or, better
const tableHeaders = [
{ dataIndex: 'DESCRIPTION' },
{ dataIndex: 'OER_HI' },
{ dataIndex: 'OER_BI' },
{ dataIndex: 'OER_SBI' },
];
return (
<div>
<Header>
<Header.Content>CPO</Header.Content>
</Header>
<Table celled>
<Table.Header>
<Table.Row>
{tableHeaders.map((header) => (
<Table.HeaderCell>{header.dataIndex}</Table.HeaderCell>
))}
</Table.Row>
</Table.Header>
<Table.Body>
{chart_8.map((data) => {
const values = tableHeaders.map((th) => data[th.dataIndex]);
return (
<Table.Row>
{values.map((v) => (
<Table.Cell>{v}</Table.Cell>
))}
</Table.Row>
);
})}
</Table.Body>
</Table>
</div>
);
};
App.tsx
:
import * as React from 'react';
import './style.css';
import 'semantic-ui-css/semantic.min.css';
import { TableChart } from './TableChart';
export default function App() {
return (
<div>
<TableChart
chart_8={[
{
DESCRIPTION: 'OER',
OER_HI: 23.23650286618332,
OER_BI: 23.419567144988942,
OER_SBI: 23.74404977161088,
},
{
DESCRIPTION: 'CPO Production',
OER_HI: 1046.17,
OER_BI: 10538.517,
OER_SBI: 87788.887,
},
{
DESCRIPTION: 'CPO Dispatch',
OER_HI: 1489.6000000000001,
OER_BI: 9145.67,
OER_SBI: 81187.22,
},
{
DESCRIPTION: 'CPO Stock',
OER_HI: 12032.43,
OER_BI: null,
OER_SBI: null,
},
{
DESCRIPTION: 'Total Oil, Losses/FFB',
OER_HI: 1.4761952,
OER_BI: 1.4469707631313098,
OER_SBI: 1.44239404903668,
},
]}
/>
</div>
);
}
Output:
Upvotes: 2