apollo-client: FetchPolicy seems to be moderately broken - summary

Like the title states, fetchPolicy in apollo-client seems to be completely moderately broken.

I thought it would be a good idea to round up all of the issues in a central place:

no-cache:

  • #3401 : update is not called in mutation when fetchPolicy set to ‘no-cache’
  • #3396 : Don’t read from cache when fetchPolicy = ‘no-cache’
  • #3272 : Response without data when fetchPolicy: ‘no-cache’ isn’t present (basically no-cache returns null)
  • #3030 : Fix no-cache fetchPolicy returns null or undefined (this was merged in v2.2.4 but still a bug in v2.3.1)
  • #2934 : support no-cache requests (breaking change)

cache-and-network:

  • #2119 : SSR and cache-and-network fetch policy
  • #3177 : fetchPolicy: ‘cache-and-network’ and client not fetching from the cache

cache-only:

  • #3343 : cache-only fetchPolicy: error not passed to Query component if query cannot be resolved from cache

network-only:

  • #1622 : Network-only refetch after network error does not update networkStatus

Misc:

  • #3243 : Refetch returned cached data
Issues related in React-Apollo repo:

network-only:

  • 556 : network-only returns cached value
  • 1895 : Fix network-only

cache-and-network:

  • 1342 : cache-and-network fetch policy on loading stage shows unrelated data
  • 1217 : Set network status to 3 with cache-and-network fetch policy

Personally l am experiencing all of the issues above in the latest version of apollo-client. It would be good to get these properly addressed as they are a pretty important part of apollo.

If anyone else has any more issues (closed or open) that can be linked into this, just comment below with it.

@evans and @jbaxleyiii Can we get this put as quite a high priority on the apollo-client Roadmap, if help is need, l can also look into these on the weekend

Version

  • apollo-client@2.3.1

Issue Labels

  • has-reproduction
  • blocking
  • bugs

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 45
  • Comments: 34 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Using fetchPolicy=no-cache for me also results in data: {}, even though the network response is present and visible.

Specifically, I end up with:

loading: false,
error: undefined,
data: {},
...

when using <Query fetchPolicy="no-cache" /> component .

   // package.json
    "apollo-cache-inmemory": "1.2.1",
    "apollo-client": "2.3.1",
    "apollo-codegen": "0.19.1",
    "apollo-link": "1.2.2",
    "apollo-link-error": "1.0.9",
    "apollo-link-http": "1.5.4",
    "react-apollo": "2.1.4"

Here is a reproduction, showing how the data is missing: https://codesandbox.io/s/4zmopq25o0

It also demonstrates different results when defaultOptions versus setting the fetchPolicy component prop is used…

Related: Using defaultOptions with a fetchPolicy for query does not seem to work - I get different behavior using defaultOptions: { query : { fetchPolicy: "no-cache" } } and <Query fetchPolicy="no-cache" />

This seems to be supported according to tests and docs

All no-cache related items listed here should now be resolved. If anyone notices any additional no-cache issues, please let me know.

@kristiehowboutdat Thanks very much for you repro in https://github.com/apollographql/apollo-client/issues/3452#issuecomment-389601457. It really helped narrow down the issue. Just so you know, your reproduction is actually demonstrating 2 separate issues. The first problem is the fact that passing a no-cache fetch policy directly into your <Query /> component is broken (which is now fixed by https://github.com/apollographql/apollo-client/pull/3777 and will be released soon). The second problem where you mentioned setting a no-cache fetch policy in defaultOptions is being ignored, is actually working as intended. React Apollo uses Apollo Client’s watchQuery functionality, instead of its query functionality. To set defaultOptions properly when using React Apollo, you need to use something like:

const client = new ApolloClient({
  ...
  defaultOptions: {
    watchQuery: {
      fetchPolicy: "no-cache"
    }
  }
});

Now of course we don’t have this documented anywhere, because we like to keep developers guessing … 🤦‍♂️.

I’ll make sure this gets added to the docs - thanks!

fetchPolicy: "no-cache" still seems to be broken

    "apollo-cache-inmemory": "1.2.5",
    "apollo-client": "2.3.5",
    "apollo-link-batch-http": "1.2.2",
    "apollo-link-error": "1.0.9",
    "apollo-link-http": "1.5.4",
    "react-apollo": "2.1.8",

Hi all - I’ll be tackling this issue in chunks, since there is a lot covered here. First up is dealing with any outstanding no-cache issues. I’ve created a new temporary label to identify outstanding no-cache related issues; if anyone knows of issues I’ve missed with the label, please let me know. Thanks!

Any workaround for this? Seems like apollo client is not usable because of this issue!

any progress on this? Im still running into the weird issue mentioned on August 9

We added a resolver that is a “cache buster” so that we send unique queries every time since the arguments are different given a unique id (using the uuid package). This only works if you can control the schema though.

query Document($documentId: String!, $uniqueId: String) {
   # Original query
  document(ID: $documentId) { ... }
  # This resolver just returns true and is used so that our query always has a unique arg
  cacheBuster(uniqueID: $uniqueId)
}
import uuid from 'uuid';
...
<Query query={documentQuery} variables={{ documentId: "1234", uniqueId: uuid.v4() }}

I also had an issue with apollo-client being used in conjunction with apollo-link-state.

If I do not explicitly specify a ‘no-cache’ fetchPolicy on the <Query> for local state, I would get stale data on page change despite proper updates on the component before page change.

@fbartho In a project in which I dont use apollo-link-state I have the same issues. The most important for me is that I have 1 view with many filters and pagination and caching is pointless there, but with cache-policy: 'no-cache' no data is rendered, despite the fact that in browser devtools I can see that response has data in it.

We use apollo-client 2.4.1 and experienced issues with no-cache:

From what we could gather, for no apparent reason, once every few times (less than 10 in our case) the Query component will trigger twice when fetchPolicy is set to no-cache. The first invocation will have the data, the second invocation will not.

We have replaced all our “no-cache” policies with “network-only” and will continue monitoring.

When I don’t set the defaultOptions for ApolloClient, it uses the ‘cache-first’ as expected, but when I set it explicit with the defaultOptions it seems to use ‘network-only’ even If I have it set to ‘cache-first’

example can be found here https://codesandbox.io/s/jjn4pnnz7v

same here::

    "apollo-boost": "^0.1.1",
    "apollo-cache-inmemory": "^1.1.9",
    "apollo-client": "^2.3.5",
    "apollo-link-context": "^1.0.7",
    "apollo-link-http": "^1.5.1",

@rajjejosefsson

When I don’t set the defaultOptions for ApolloClient, it uses the ‘cache-first’ as expected, but when I set it explicit with the defaultOptions it seems to use ‘network-only’ even If I have it set to ‘cache-first’

example can be found here https://codesandbox.io/s/jjn4pnnz7v

The react Query component uses watchQuery and not query. If you change the defaultOption of watchQuery to 'cache-first' then it works as expected.

I have fixed your example here https://codesandbox.io/s/68q5p5vow

All no-cache related items listed here should now be resolved. If anyone notices any additional no-cache issues, please let me know.

@kristiehowboutdat Thanks very much for you repro in #3452 (comment). It really helped narrow down the issue. Just so you know, your reproduction is actually demonstrating 2 separate issues. The first problem is the fact that passing a no-cache fetch policy directly into your <Query /> component is broken (which is now fixed by #3777 and will be released soon). The second problem where you mentioned setting a no-cache fetch policy in defaultOptions is being ignored, is actually working as intended. React Apollo uses Apollo Client’s watchQuery functionality, instead of its query functionality. To set defaultOptions properly when using React Apollo, you need to use something like:

const client = new ApolloClient({
  ...
  defaultOptions: {
    watchQuery: {
      fetchPolicy: "no-cache"
    }
  }
});

Now of course we don’t have this documented anywhere, because we like to keep developers guessing … 🤦‍♂️.

I’ll make sure this gets added to the docs - thanks!

Using this approach:

const client = new ApolloClient({
  uri: 'https://graphql-pokemon.now.sh/',

  // Disable caching
  defaultOptions: {
    watchQuery: {
      fetchPolicy: 'no-cache'
    }
  }
})

causes Console warning:

ApolloBoost was initialized with unsupported options: defaultOptions

meet the same issue

I am not sure about this one it is just my quick observation but it seems that when using withApollo calling query with no-cache does not work at all it always updates the cache.

Thanks for putting this list together @OllieJennings! I’ve been working through all outstanding apollo-client issues, and will be getting to these shortly.

if help is need, l can also look into these on the weekend

Help is 💯% always welcome! If you’re able to chip in by reviewing these issues and adding your comments, helping with reproductions, or better yet, working on PR’s, that would be awesome!