apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.38k stars 2.66k forks source link

cache.writeQuery() delete object not update #6068

Closed zaquas77 closed 3 years ago

zaquas77 commented 4 years ago

Intended outcome: I want to clear partial of my localdata in cache:

For example

cache.writeData(
{
    data: {
        user: {
            __typename:  'User',
            email:  'myemail@localhost'
        },
        isLoggedIn:  true
    }
}); 

The cache have this data:

{user: {__typename: 'User',email: 'myemail@localhost'}, isLoggedIn: true}

But If I update with

cache.writeData(
{
    data: {
        user: {
            __typename:  'User'
        },
        isLoggedIn:  true
    }
}); 

Actual outcome: The cache continues having the same data:

{user: {__typename: 'User',email: 'myemail@localhost'}, isLoggedIn: true}

How to reproduce the issue: https://codesandbox.io/s/zealous-dan-63hbj

Versions System: OS: macOS 10.15.3 Binaries: Node: 12.13.0 - /usr/local/bin/node npm: 6.13.0 - /usr/local/bin/npm Browsers: Chrome: 80.0.3987.149 Firefox: 74.0 Safari: 13.0.5 npmPackages: @apollo/client: ^3.0.0-beta.41 => 3.0.0-beta.41

zaquas77 commented 4 years ago

I have investigate a little more and I found a gap in configuration of my "useQuery" hook. If I add the property "returnPartialData" setting to true on option "userQuery", it seem works.

here that updated (look at ExchangeRates.jsx:25)

https://codesandbox.io/s/silly-hill-6b0mc

Is it correct use of that option? However if I try the same thing with apollo client 2.6 it continues failing. Have some idea?

thanks

KennyHammerlund commented 4 years ago

I think your Query was getting in your way. They dislike anonymous queries in Apollo Client (those without a query name such as query MyQuery{...}). They might be forcing them in beta as I thinking the names are used for query watches. Also I am not sure that you need @client(always: true) and I think children of a @client directive automatically get the client directive attached.

working sandbox: https://codesandbox.io/s/vibrant-heyrovsky-eph49

const EXCHANGE_RATES = gql`
  query GetRates {
    isLoggedIn @client
    user @client {
      email
    }
    rates(currency: "USD") {
      currency
      rate
    }
  }
`;
KennyHammerlund commented 4 years ago

My first comment was probably off topic. I saw what your real issue was with deleting and the cache not updating. There was a couple small issues.

cache.writeQuery => client.writeQuery you were using client.mutate, while I dont think this was causing issues I think its probably bad practice and you should use the useMutation hook. The biggest problem was that you were sending in an empty object rather than null to reset the object. So when you say writeQuery with data only being { typename: 'User' } it is not actually writing anything because you are only telling it to write the `typenamefield. The sandbox I made setsUser: null` you could also pass in { __typename: 'User', email: null } Then the cache knows to overwrite that field.

zaquas77 commented 4 years ago

Hi Kenny! You are right... I wrote the code after many hours of headache and fighting with apollo... So for now Apollo vs Stefano = 1 vs 0 :D Thanks for your explanation!

hwillson commented 3 years ago

Answered by https://github.com/apollographql/apollo-client/issues/6068#issuecomment-604420865 - thanks!