Reputation: 51
I'm doing a leaderboard for a game. The userInfo array that i am using contains fetched data from a json table. The array contains id
, username
, bestattempts
and besttime
along with the data from each category.
This table currently have 4 columns and all the data from the json table is on table rows. I need to have the table not showing the data of the users that have bestattemps < 5
or besttime === 0
. I'm trying to filter the data from the array but it's not working and i am getting this error: TypeError: Cannot convert undefined or null to object
on this line const keys = Object.keys(newArray[0])
Here's the code:
import React from "react";
import "./LeaderBoard.css";
const Head = ({keys, head}) => {
return (
<thead>
<tr>
{
keys.map(key =><th key={key}>{head[key] || key}</th> )
}
</tr>
</thead>
)
}
const Row = ({row}) => {
const keys = Object.keys(row)
return (
<tr key={row.Rank}>
{
keys.map(key => <td key={key}>{row[key]}</td>)
}
</tr> )
}
const LeaderBoard = ({usersInfo, head}) => {
usersInfo.sort(function sortByAttempts(a, b) {
if(a.bestattempts !== b.bestattempts){
return a.bestattempts - b.bestattempts
}else{
return a.besttime - b.besttime
}
});
const newArray = usersInfo.map(({ id, ...rest }, index) => ({ Rank: index + 1, ...rest }) )
const keys = Object.keys(newArray[0])
const filteredData = newArray.filter(usersInfo => usersInfo.bestattempts >= 5 && usersInfo.besttime !== 0);
return (
<div className="Leaderboard-wrapper">
<table>
<Head keys={keys} head={head}/>
<tbody>
{
filteredData.map((row) => <Row row={row}/>)
}
</tbody>
</table></div>
)
};
export default LeaderBoard;
On app.js as a prop
const head = {
id: "ID",
username: "Username",
bestattempts: "Best Attempts",
besttime: "Best Time",
}
Upvotes: 0
Views: 76
Reputation: 1712
You probably want to hardcode the headers. Instead of relying on the data from filter which can result with empty array and hence array[0]
throws, think about hardcoding your headers. Small change such as const keys = ['Rank', 'username', 'bestattempts', 'besttime'].
Besides eventually you will want the header values not to be dependent on keys describing your objects. I would also recommend changing the implementation of Row and instead of doing a loop in all keys, decide the order in which you want to return them. Something like
<td>{row['Rank']}</td>
<td>{row['username']}</td>
<td>{row['bestattempts']}</td>
<td>{row['besttime']}</td>
This way you have full control of the ordering of the values.
Upvotes: 1