0
votes

In my app, when I insert new data into input field and fire the mutation. The data gets stored in Db (MongoDB), however, Apollo doesn't return the updated data. On initial load, the data (i.e, the 'song' property is retrieved & displayed as per the React component code). However, its when a new content is pushed through mutation & subsequent data update is required, Apollo doesn't return the 'song' property & this loads the <div>loading...</div> line of the React component code below. The error is resolved when I refresh the page.

My React component is:

class SongDetail extends Component{
   render(){
      const { song } = this.props.data;
      console.log( "song details are...", this.props, "---", song );
      if( !song ) return <div>loading...</div>;
      return(
         <div>
            <Link to = "/">Back</Link>
            <h3>{ song.title }</h3>
            <LyricList lyrics = { song.lyrics }/>
            <LyricCreate songId = { this.props.params.id }/>
         </div>
      );
   }
}

export default graphql( fetchSong, {
   options : ( props ) => {
      return { variables : { id : props.params.id }};
}})( SongDetail );

The 'fetchSong' query is as follows:

const fetchSong = gql`
   query fetchSong( $id : ID! ){
      song( id : $id ){
         id,
         title,
         lyrics {
            id,
            content
         }
      }
   }
`;

I am using the configuration option to map the id across the store.

const client = new ApolloClient({
   dataIdFromObject : o => o.id
});
...
      <ApolloProvider client = { client }>
...

I am not sure what more information would be helpful from the app. To reiterate what I wrote above: The LyricCreate component is successfully storing new content into store via mutation query. However, Apollo does not update by retrieving the song property after new lyric content is stored.

1
Probably a caching issue. If I understand correctly, the apollo client correctly retrieves the information on loading but does not update it when you trigger a mutation by interacting with the LyricCreate component. I would put the data retrieval in a separate function and either set the fetchPolicy of the apollo client or trigger the update callback to manually update my cache. apollographql.com/docs/react/basics/… or howtographql.com/react-apollo/… (Updating the cache)devconnected

1 Answers

-1
votes

your code looks good , but why using if( !song ) return <div>loading...</div>;? maybe we should try :

class SongDetail extends Component{
   render(){
      const { song, loading } = this.props.data;
      console.log( "song details are...", this.props, "---", song );
      if( loading ) return <div>loading...</div>; // loading = false when done loading and ready
      return(
         <div>
            <Link to = "/">Back</Link>
            <h3>{ song.title }</h3>
            <LyricList lyrics = { song.lyrics }/>
            <LyricCreate songId = { this.props.params.id }/>
         </div>
      );
   }
}