Can't render data returned from server in React App. HELP!

I am working on a expense splitting app and have saved user details in firebase database. Now I am trying to fetch the user details from Firebase DB in ComponentDidMount method and rendering it to screen.

The problem is that the user details are not appearing immediately. It’s only when I do something in the app, the user details appears in the screen. I know it is the async behavior that is stopping the details to appear right away.

But there has to be a way to get the details as soon as the promise is resolved inside ComponentDidMount method.
How do I go about it?
Here is the code snippet:

this.state = {
      friendsList:[]
    };
  componentDidMount() {
    let friendsList = [];
    firebase.database().ref("friendsList")
    .once('value')
    .then((snapshot) => {
      snapshot.forEach((childSnapshot) => {
        friendsList.push({
          ...childSnapshot.val(),
          id:childSnapshot.key
        })
      })
    }) 
    this.setState({friendsList})
  }
const {friendsList} = this.state
// snippet from the react render call below
<div className={classes.friendsDashboard}>
          {friendsList.map(friend => {
            return (
              <div>
                {friend.name}
              </div>
            );
          })}
        </div>

Any help/hint/suggestion would be greatly appreciated.
Happy New Year! :slight_smile:

Okay, let’s do a bit of analysis.
After initial render componentDidMount gets called. You made your firebase call… which returns a promise. And after the firebase thing you run setState.
Remember firebase returns a promise, and without await keyword in front of the firebase call, setState probably runs before the call made to firebase is completed.

I am not this completely sure this will solve it, but at a quick look here is what I’d suggest:
Either move your setState just one line above into the last then block such that it runs immediately after the forEach or define an function in componentDidMount with async await syntax and await in front of the firebase call, like so :

await firebase.database...
1 Like

Move this inside .then callback after friendsList.push … . That will do.
The problem is that you set as state empty array before the Promise and the “then” are resolved.

1 Like

@samolex @GeorgeCrisan It worked and it make sense to have the setState call inside the then. Thank you guys for your help! You guys have a wonderful year ahead. :slight_smile:

2 Likes