apollo-client: Fetch policy no-cache returns null data
Intended outcome:
Run a query and receive non-null data when using fetchPolicy: 'no-cache'
. Tested on Node and in Browser.
client.query({query, fetchPolicy: 'no-cache'})
Actual outcome:
The data
property is null
:
{
data: null
loading: false
networkStatus: 7
stale: true
}
How to reproduce the issue:
Node.js
- Visit this runkit and fork it: https://runkit.com/razorx/apollo-client-no-cache/4.0.1
- Run the first box to initialize.
- Run the second box to run a query with the default fetch policy: the Promise will eventually resolve with good data (
data: {...}
). (expected) - Run the second box to run a query with the
no-cache
fetch policy: the Promise will eventually resolve with no data (data: null
). (unexpected) - Run the second box to run a query with the
network-only
fetch policy: the Promise will eventually resolve with good data. (expected)
Browser
- Visit https://codesandbox.io/s/znx9n9x943
- Run the code with the “refresh” button in the right pane.
clientA
works with default fetch policy: returns non-null data. (expected)clientB
does not work withno-cache
fetch policy: returnsnull
data. (unexpected)clientC
works with default fetch policy (returns non-null data), then the query is repeated again withclientC
, this time withno-cache
fetch policy, and the data returns non-null! (what?)
Version
- apollo-client@2.2.3
Contents of the runkit for reference
require('isomorphic-fetch')
require('graphql')
const { ApolloClient } = require('apollo-client')
const { HttpLink } = require('apollo-link-http')
const { InMemoryCache } = require('apollo-cache-inmemory')
const gql = require('graphql-tag')
const uri = 'https://graphql-pokemon.now.sh/graphql'
const query = gql`{
pokemon(name: "Pikachu") {
id
number
name
}
}`
const client = new ApolloClient({
link: new HttpLink({uri}),
cache: new InMemoryCache()
})
client.query({query})
.then(data => console.log(data))
.catch(error => console.error(error))
// => gives good data
const clientNoCache = new ApolloClient({
link: new HttpLink({uri}),
cache: new InMemoryCache()
})
clientNoCache.query({query, fetchPolicy: 'no-cache'})
.then(data => console.log(data))
.catch(error => console.error(error))
// => gives NULL data
const clientNetworkOnly = new ApolloClient({
link: new HttpLink({uri}),
cache: new InMemoryCache()
})
clientNoCache.query({query, fetchPolicy: 'network-only'})
.then(data => console.log(data))
.catch(error => console.error(error))
// => gives good data
Contents of the browser example for reference
import { gql, graphql } from 'react-apollo';
import { ApolloClient } from 'apollo-client';
import { HttpLink } from 'apollo-link-http';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloProvider } from 'react-apollo';
import App from './App';
const uri = 'https://qkv3mq9rp.lp.gql.zone/graphql'
const clientA = new ApolloClient({
link: new HttpLink({uri}),
cache: new InMemoryCache()
});
const clientB = new ApolloClient({
link: new HttpLink({uri}),
cache: new InMemoryCache()
});
const clientC = new ApolloClient({
link: new HttpLink({uri}),
cache: new InMemoryCache()
});
const query = gql`{
people {
id
name
}
}
`
clientA.query({query})
.then(data => document.write('A cache<br \><br \>' + JSON.stringify(data)))
.then(() => clientB.query({query, fetchPolicy: 'no-cache'}))
.then(data => document.write('<br \><br \>B no-cache<br \><br \>' + JSON.stringify(data)))
.then(() => clientC.query({query}))
.then(data => document.write('<br \><br \>C cache<br \><br \>' + JSON.stringify(data)))
.then(() => clientC.query({query, fetchPolicy: 'no-cache'}))
.then(data => document.write('<br \><br \>C no-cache<br \><br \>' + JSON.stringify(data)))
.catch(error => console.error(error))
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 25
- Comments: 34 (3 by maintainers)
Commits related to this issue
- Merge branch 'master' into bug/GH-3030/no-cache-undefined — committed to kamranayub/apollo-client by kamranayub 6 years ago
- Merge branch 'master' into bug/GH-3030/no-cache-undefined — committed to kamranayub/apollo-client by kamranayub 6 years ago
- Merge branch 'master' into bug/GH-3030/no-cache-undefined — committed to kamranayub/apollo-client by deleted user 6 years ago
- [#3030] Fix no-cache fetchPolicy returns null or undefined (#3102) * Set query newData if using no-cache fetch policy and set resultFromStore * Add tests for no-cache fetch policy * Get VSCode ... — committed to apollographql/apollo-client by kamranayub 6 years ago
- diffQueryAgainsStore set returnPartialData to false Is there a reason why returnPartialData is true? This was hiding an error and returning { data: undefined, networkState: 7, stale: true } for me. ... — committed to quazzie/apollo-client by quazzie 6 years ago
After several trails I figured
data
is always null whenever there are missing fields from the projected result. For instance, if we’re supposed to query an user like:user { uuid email picture }
and for some reason the server does not return fieldpicture
, then result will be:I’ve also noticed we’ll get a
Missing field picture
warning on the console.In my particular case, my backend never serializes
null
values. Since user’s picture and many other fields are optional (nullable), we constantly face this problem.Does anyone have an idea why those missing fields break the result causing this issue?
Have same issue on apollo-client@2.4.12, why this is closed?
Any updates on this?
I’m actually experiencing this issue from multiple sides. In some cases, the query works with “network-only” but does not work with “no-cache”, whereas, in other queries, “network-only” does not work, but “no-cache” does. I’ve tried to see whether my issue might be related to the missing fields @jdorleans mentioned, but that does not seem to be the case. Oh, and data indeed does seem to be
undefined
instead ofnull
, as @sreuter mentioned. Somehow, reloading the whole page does seem to solve the issue & everything is fetched properly.Why is this closed again? There’s not even a workaround, save an actual fix for this.
@rschef I need this to work in a system which doesn’t know about react and uses this client directly, so unfortunately that workaround won’t be an option for me.
I poked around a little in QueryManager.ts but I couldn’t find an obvious reason for this bug.
I’m hoping someone more familiar with the code will be able to prioritize and find this quickly. I would consider this a serious bug as I could rephrase the issue as apollo-client does not support the most basic GraphQL operation: running a query and returning the correct result (without the added complexity of caching).
I’m still having this issue (data is {}) on 2.4.2
@kamranayub this issue still persists randomly.
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 tono-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.
Please re-open this issue or let me know if I need to open a new one.
We encountered this issue and resolved via insight from @jdorleans’s comment. When the response does not include a field you’re expecting the entire
data
object will be null.The same problem with the Query component. It returns normal data once, then data = {} with the same query (nothing is changed just component is rerendered) when fetchPolicy is ‘no-cache’
This was fixed in release 2.3.8 by hwillson
@jdorleans You have no idea how many hours you saved me. I was going in a rabbit hole trying to find the answer. Thank you
This insight from @jdorleans resolved the issue for me.
I still having the same issues with
apollo-client@2.5.1
. It only works the first query, if you request the same data always is empty, if you change some fields it works only the first request.Still having the same issues as @bozskejkaja Neither no-cache or network-only are working for me when making @client side queries.
Confirming that this is still an issue. We’re encountering this when mocking network requests during E2E tests with Cypress.
I have the same issue as @thanpolas, also happening erratically. Running version
2.4.7
ofapollo-client
. If Iconsole.log
thenetworkStatus
, I see that in the cases where it breaks it logs:instead of the expected:
It’s this code: https://github.com/apollographql/apollo-client/blob/6eec674f206cda11cf667a89022354b1476f5503/packages/apollo-client/src/core/QueryManager.ts#L1059-L1112
It was introduced in https://github.com/apollographql/apollo-client/pull/2934
Basically, if
fetchMoreForQueryId
is not present, it tries to get the result from the cache even though it was never set (right above,if (fetchPolicy !== "no-cache")
).The branch needs to be updated to use
result.data
ifno-cache
is used, I think:Not sure what implications that has.
I’m running into this right now because the cache actually seems to be causing performance issues in our use case and I wanted to try bypassing it; but I can’t due to this bug 😦 If I can figure out how to develop this locally, I could try updating it.
@jbaxleyiii Should I try to update the branch as I mentioned to fix this issue? Do you see any issues with that approach?