0
votes

I have retrieved data from my Firebase-database, and displayed it correctly earlier using a map function. This is the list of objects retrieved correctly

This time I tried to retrieve the sorted list using orderbychild, and I tried to map over the list, but it wont enter the map function. I have console logged the state which says what shows this in the picture. It seems to be and empty list, but it still has objects inside

Here is the file: https://pastebin.com/RLJMpzWN

Here is the Firebase setup

My question is, how do I display my list of objects?

import React from "react";
import { StyleSheet, View, Text, FlatList } from "react-native";
import firebase from 'firebase/app';




export default class Card extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      highScoreList: null,
      isDataLoaded: false
    }
  }


  componentDidMount() {
    const hList = [];
    const ref = firebase.database().ref('users')
    ref.orderByChild('hours').on('child_added', function(snapshot) {
      hList.push({
        id: snapshot.key,
        hours: snapshot.val().hours,
        name: snapshot.val().name
      });
    });

    this.setState({
      highScoreList: hList,
      isDataLoaded: true
    })



  }



  render(){
    if(this.state.isDataLoaded && this.state.highScoreList){

      return (
        <View style={styles.card}>
          {this.state.highScoreList.map( user => <Text key = {user.key} style = {{textAlign: 'center', marginBottom: 10}}>{user.name}        {user.hours}</Text>)}
        </View>
      )
    }else{
      console.log("State var tom")
      return (<Text> Waiting for data</Text>)
    }
  }

}




const styles = StyleSheet.create({
  card: {
    flex: 1, flexDirection: 'row',
    backgroundColor: "#fff",
    paddingVertical: 20,
    paddingHorizontal: 10,
    borderRadius: 20,
    minHeight: 333
  },
  text: {
    fontSize: 30,
    marginBottom: 20,
    color: "black",
  },
});
1

1 Answers

0
votes

@Simen96 I would recommend you to refactor your component to something like this:

  constructor(props) {
    super(props);
    this.state = {
      highScoreList: [],
      isDataLoaded: false
    }
  }

 componentDidMount() {
    const ref = firebase.database().ref('users')

    ref.orderByChild('hours').on('child_added', snapshot => {
      this.state.highScoreList.push({
        id: snapshot.key,
        hours: snapshot.val().hours,
        name: snapshot.val().name
      });
    });
  }

render(){
    if(this.state.highScoreList.length){

      return (
        <View style={styles.card}>
          {this.state.highScoreList.map( user => <Text key = {user.key} style = {{textAlign: 'center', marginBottom: 10}}>{user.name}        {user.hours}</Text>)}
        </View>
      )
    }else{
      console.log("State var tom")
      return (<Text> Waiting for data</Text>)
    }
  }

The function componentDidMount and the 'child_added' callback will not execute sequentially because 'child_added' callback is asynchronous and setState will not wait for this callback to be triggered.