6
votes

I have the following button in a flatlist that triggers a graphql mutation and after the mutation I do a writeQuery to update the local cache (store). In the update functionf of the mutation I am updating two fields within the cache. essentially when the user touches the like button I chang the boolean value of the like to true and update the like count for that post by +1 (similiar to twitter). However the components in the flatlist do not get updated. I even printed out the apollo store/cache and I see the values getting updated. why is the flatlist not re-rendering after the cache write?

   render() {


 const { posts, isFetching, lastUpdated, location, navigation, data, likeMutation, username, distancePointLatitude, distancePointLongitude, searchPointLatitude, searchPointLongitude } = this.props


 <FlatList
  data={data.near}
  style={styles.scrollViewContent}
  extraData={this.props.store}
  //renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.separator} />}
  showsVerticalScrollIndicator={false}
  onRefresh={this._onRefresh.bind(this)}
  refreshing={this.state.refreshing}
  keyExtractor={this._keyExtractor}
  renderItem={({item, index}) => item.posts.length != 0 && <ListItem>

{item.posts[0].userInteraction.userLike ? <Icon name='md-heart' style={{ color: 'crimson',fontSize: 28}} /> 
          : <Icon name='heart' style={{ fontSize: 26}} 

          onPress={() => likeMutation({ variables: { elementId: item.posts[0].postId, userId: username  },

            update: (store, { data: { addLike } }) => {
              // Read the data from our cache for this query.

              var thisLocationRadius = {searchPointLongitude: searchPointLongitude,
                searchPointLatitude: searchPointLatitude,
                radius: fiftyMilesInMeters, distancePointLongitude: distancePointLongitude,
                 distancePointLatitude: distancePointLatitude };


              var data = store.readQuery({ query: getLocalPosts,
                variables: {
                locationRadius: thisLocationRadius,
                userId: username
              }, });


             data.near[index].posts[0].userInteraction.userLike = true

              data.near[index].posts[0].interactionStats.totalLikes + 1


              // Write our data back to the cache.
              store.writeQuery({ query: getLocalPosts, data });



            },
          }).catch((error) => {
          console.log('there was an error sending the query', error);
          })} />  }
}

  const HomeWithData = graphql(getLocalPosts, {
        options:  ({ searchPointLongitude, searchPointLatitude, distancePointLongitude, distancePointLatitude, username }) => ({ variables: { locationRadius: {searchPointLongitude: searchPointLongitude,
           searchPointLatitude: searchPointLatitude,
           radius: fiftyMilesInMeters, distancePointLongitude: distancePointLongitude,
            distancePointLatitude: distancePointLatitude }, userId: username } }),

        });


export default compose( connect(mapStateToProps),
HomeWithData,
graphql(like, { name: 'likeMutation' }))(Home);

getLocalPosts Query:

export const getLocalPosts = gql`query getLocalPosts($locationRadius: locationRadius!, , $userId: String!) {
    near(locationRadius: $locationRadius){
      name,
      address,
      phonenumber,
      email,
      website,
      about,
      location {
        longitude,
        latitude
      },
      distance(unit: MILE),
      businessId,
      hours {
        weekDay,
        startTime,
        endTime
      },
      posts(isActive: true) {
        postText,
        postId,
        userInteraction(userId: $userId){
          userLike
        },
        interactionStats{
          totalLikes
        }
      },
    }
    }`;
1
Can you post the code where you defined your query operation and connected it to the flat list? - Tal Z
@TalZ I have added the code you requested that contains my query operation and how it is connected to flat list. - john

1 Answers

18
votes

I think that Apollo takes into account a few things when it decides which query listener should be triggered after a change, including the variables field.

In your case, your component with the flat list is not re-rendered because the query isn't notified of a change. It isn't notified of a change because Apollo thinks it is a different query than the one you are updating in the store when you call writeQuery.

So the solution is to add the variables field when you call writeQuery. And it should have the same values you use when the query is called.

Assuming these have the correct values, your call to store.writeQuery should look something like this:

          store.writeQuery({ 
            query: getLocalPosts, 
            data, 
            variables: {
              locationRadius: thisLocationRadius,
              userId: username
            }
          });