tabrez
tabrez

Reputation: 146

Table is not showing data accordingly in Reactjs

I am trying to show the response from API into the react-semantic-ui table. After setting the state with fetch data, I need to place the first-order keys as the column name and then the second-order keys as the row name and the values of the second-order keys will be shown in the table-body. I have done this far which results in doubling the number of cells in each row while setting all cell values with the same data.

class NonProtectedFeatureBias extends Component {
    constructor(props){
        super(props);
        this.state = {       
            staticPostData:{
                dataset_id: 1
            },
            tableData:{},
            tableColumnNames:[],
        };
    }
    renderKeys (data) {
        let tcolumn = [];
        for(let i=0; i<Object.keys(data).length;i++){
            const Obj1 = Object.keys(data)[i];
            //console.log(Obj1)
            tcolumn.push(Obj1);

        }
        let col = tcolumn.map(item=>{
            return <Table.HeaderCell>{item}</Table.HeaderCell>
        })
        return col
    }
    renderValues (data) {
        let row=null;
        for(let i=0; i<Object.keys(data).length;i++){
            const Obj1 = Object.values(data)[i];

            let trows = [];
            const Obj2 = Object.keys(Obj1).map(item =>{
                trows.push(item);
            });

            let tvalues =[];
            const Obj3 = Object.values(Obj1).map(item =>{
                tvalues.push(item);
                console.log(item)
            });
            row = trows.map(item=>{
                return(
                    <Table.Row  className="cell-current">
                        <Table.Cell className="cell-width-single">{item}</Table.Cell>
                        {tvalues.map(val =>{
                            return <Table.Cell selectable>{val}</Table.Cell>
                            //console.log(val)
                        })}
                    </Table.Row>
                )
            })
        }

        return row
    }

    componentDidMount() {
        this.fetchData();
    }
    fetchData(){
        axios.post('http://localhost:5000/GetProxyTable', this.state.staticPostData)
         .then((response) =>{

            var count = Object.keys(response.data).length;
            this.setState({tableData:response.data})
            console.log(response.data)
        });
    }
    render(){
        return ( 
            <Container style={{height:"250px", backgroundColor:""}}>
                <Table definition >
                    <Table.Header>
                    <Table.Row className="cell-with-no-padding">
                        <Table.HeaderCell />
                        {this.renderKeys(this.state.tableData)}
                    </Table.Row>
                    </Table.Header>

                    <Table.Body>
                        {this.renderValues(this.state.tableData)}
                    </Table.Body>
                </Table>
            </Container>
        );
    }
}
export default NonProtectedFeatureBias;

This is the response I get from the API

enter image description here

And this is what I want to achieve, enter image description here

This is what I am getting now, enter image description here

Is this the right approach to achieve my goal?! I hope there is a much-optimized way to do this. And I am also needed to be able to click on a cell and get the regarding row and column name. Any suggestions or advice will be much appreciated.

Upvotes: 1

Views: 667

Answers (1)

buzatto
buzatto

Reputation: 10382

your renderValues are mapping through columns and not rows. Plus, you are setting each fake row to the same values, so all 'rows' are equal. lastly, returns the last one, which means last column values.

you can try code below which maps the columns to a rows object first before rendering the rows:

renderValues (data) {
  const rows = {}
  Object.values(data).forEach(col => {
    for (let [key, value] of Object.entries(col)) {
      rows[key] = rows[key] ? [...rows[key], value] : [value]
    }
  })

  return Object.entries(rows).map(([item, values]) => (
    <Table.Row className="cell-current">
      <Table.Cell className="cell-width-single">{item}</Table.Cell>
        { values.map(val => <Table.Cell selectable>{val}</Table.Cell> ) }
    </Table.Row>
  ))
}

Upvotes: 2

Related Questions