3
votes

I have a page that consists of 2 components and each of them has its own request for data for example

<MovieInfo movieId={queryParamsId}/>

const GET_MOVIE_INFO = `gql
  query($id: String!){
   movie(id: $id){
    name
    description
 }
}`

Next component

<MovieActors movieId={queryParamsId}/>

const GET_MOVIE_ACTORS = `gql
  query($id: String!){
   movie(id: $id){
    actors
 }
}`

For each of these queries I use apollo hook

const { data, loading, error } = useQuery(GET_DATA, {variable: {id: queryParamsId}}))

Everything is fine, but I got a warning message:

Cache data may be lost when replacing the movie field of a Query object. To address this problem (which is not a bug in Apollo Client), either ensure all objects of type Movie have IDs, or define a custom merge function for the Query.movie field, so InMemoryCache can safely merge these objects: { ... }

It's works ok with google chrome, but this error affects Safari browser. Everything is crushing. I'm 100% sure it's because of this warning message. On the first request, I set Movie data in the cache, on the second request to the same query I just replace old data with new, so previous cached data is undefined. How can I resolve this problem?

4
in other words: "your queried (requested) movie [type] should contain id property" (beside name, description or actors) - otherwise it is not cache'able - [you can use other named unique field and conversion function] - cache just works this way, it wants unique objectsxadm
"ensure all objects of type Movie have IDs" is quite clear imoBergi

4 Answers

2
votes

Solved!

 cache: new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          YOUR_FIELD: {
            merge(existing = [], incoming: any) {
              return { ...existing, ...incoming };
              // this part of code is depends what you actually need to do, in my 
              case i had to save my incoming data as single object in cache
            }
          }
        }
      }
    }
  })
});
2
votes

Here is the same solution mentioned by Thomas but a bit shorter

const cache = new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        YOUR_FIELD: {
          merge: true,
        },
      },
    },
  },
});
0
votes

Had same issue with inconsistency of data values vs. our schema. A value type within an entity was missing the id value. Caused by an incomplete data migration.

Temporary solution:

const typePolicies = {
      PROBLEM_TYPE: {
        keyFields: false as false,
      },
      PARENT_TYPE: {
        fields: {
          PROBLEM_FIELD: {
            merge: true
          }
        }
      }
    }
0
votes

The other answers still work, but as of Apollo Client >= 3.3 there's an easier option that doesn't require specifying specific fields or a custom merge function. Instead, you only have to specify the type and it will merge all fields for that type:

const cache = new InMemoryCache({
  typePolicies: {
    YOUR_TYPE_NAME: {
      merge: true,
    }
  }
});