Reputation: 71
I'm trying to map an array of objects to table rows in React. I've tried countless suggestions on this site but nothing seems to render in the end.
I'm getting the array data from the db on componentWillMount
as so:
componentWillMount(){
db.collection("games")
.onSnapshot(function(querySnapshot){
querySnapshot.forEach(function(doc){
games.push(doc.data())
});
console.log(games);
})
}
The data is loading properly as seen in games
. games
is declared as a global variable outside the react class.
So far I've tried mapping over the array like this:
renderRow = () => {
games.map(function(val, i){
return(
<tr>
<td key={i}>
{val.name}
</td>
</tr>
)
})
}
And then rendering it in the table like so:
<table className="ui inverted table">
<thead>
<tr>
<th>Lobby name</th>
<th>Players</th>
<th>Mode</th>
<th>Difficulty</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{this.renderRow()}
</tbody>
</table>
But nothing seems to render. I'm not sure if i'm not mapping over it properly, or perhaps it's rendering the table values before the array is loaded with data. Any thoughts on this?
Edit: console.log(games)
gives this:
(10) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0:
currentPlayers: 1
difficulty: ""
gameMode: "family"
host: "###########"
name: "Testing new reset"
players:
player: "###########"
__proto__: Object
timestamp: 1550704627051
__proto__: Object
1: {currentPlayers: 1, difficulty: "heroic", gameMode: "experienced", host: "", name: "Testtest", …}
2: {currentPlayers: 1, difficulty: "veteren", gameMode: "experienced", host: "", name: "Flashpoint experts only!", …}
Upvotes: 5
Views: 5875
Reputation: 690
If the function you are calling in componentWillMount
to fetch the games is asynchronous it may be that your React component renders before your data is fetched.
You should try to set the state of the component when the games
array is fetched and the React will re-render the component.
eg.
class Games extends React.Component {
constructor(props) {
super(props)
this.state = {
games: []
}
}
componentWillMount() {
db.collection("games")
.onSnapshot(function (querySnapshot) {
let gamesArray = []
querySnapshot.forEach(function (doc) {
gamesArray.push(doc.data())
});
this.setState({ games: gamesArray })
})
}
renderRow = () => {
return this.state.games.map(function (val, i) {
return (
<tr>
<td key={i}>
{val.name}
</td>
</tr>
)
})
}
render() {
return (
<table className="ui inverted table">
<thead>
<tr>
<th>Lobby name</th>
<th>Players</th>
<th>Mode</th>
<th>Difficulty</th>
<th>Status</th>
</tr>
</thead>
<tbody>
{this.renderRow()}
</tbody>
</table>
)
}
}
Upvotes: 1
Reputation: 33994
You are not returning anything in renderRow so need to add return before games.map
Change
renderRow = () => {
games.map(function(val, i){
return(
<tr>
<td key={i}>
{val.name}
</td>
</tr>
)
})
}
To
renderRow = () => {
return games.map(function(val, i){
return(
<tr>
<td key={i}>
{val.name}
</td>
</tr>
)
})
}
Upvotes: 5