-2

**I am trying to filter out posts from blocked users. **

I made an async function to check if a user is blocked or not:

checkBlocked = async userId => {
  try {
  let snapshot = await firebase.database().ref('Blocked/' + firebase.auth().currentUser.uid).orderByChild('uid').equalTo(userId).once('value')
    return snapshot.exists();
  }
  catch(error) {
    return false;
  }
}

I want to return the value inside flatlist so that accordingly the post shows up there:-

<FlatList
        inverted
        extraData={this.state.blocked}
        data={this.state.arrData}
        keyExtractor={item => item.key}

        renderItem={({ item }) => {
         
         
          this.checkBlocked(item.id).then(val => this.setState({blocked: val}));
         
            if(this.state.blocked == true){
              return (
              //something
                 )
            }

          else {
             
          return (
            //something
                 )
            }
         }}

The above approach is not working, where am I going wrong?

1 Answers1

0

We don't have all the details exactlty, but I can see the logic flow here is strange. Let's look at what's happening

  1. FlatList renders with this.state.arrData
  2. On each iteration of renderItem, checkBlocked makes an async call with the id of a user
  3. You render something based on this.state.blocked
  4. Your checkBlocked promise resolves, and the blocked variable in state is overwritten with the returned value

You are making a promise (checkBlocked(id).then()), but your render does not wait for that promise to resolve before it returns something. So your this.state.blocked is not yet defined as what you think in your return statement. Also, setState is async, meaning you can't rely on the value in your return statements to be the value you just set from checkBlocked.

A better pattern would be to that before you render your component, run your userlist through an async loop, where each entry is checked with checkBlocked. You can then construct an array of objects, say usersWithBlockedStatus, each object with a user name and blocked status. Then you filter out all entries who's blocked status is true, and call it usersThatAreNotBlocked. Only once all this is complete, you render your FlatList with the data as usersThatAreNotBlocked.

You can find another well written explanation in the question How to call fetch() inside renderItem on FlatList?

Seth Lutske
  • 9,154
  • 5
  • 29
  • 78
  • Thank you so much!!! I made a separate array of blocked users in componentDidMount and then checked whether the user id exists in the blocked users array, if not print the posts. Thank you so much, i was able to think of this approach just because of you! – Vaibhav Dagar Oct 31 '20 at 08:04
  • Happy to help . – Seth Lutske Oct 31 '20 at 14:57