0

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:

table

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?

enter image description here

2 Answers 2

2

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:

enter image description here

stackblitz

Sign up to request clarification or add additional context in comments.

Comments

0
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])

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.