Reputation: 146
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
And this is what I want to achieve,
This is what I am getting now,
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
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