Intended outcome:
This is the issue I originally found but it appears that the issue is with the client
and not the Query
component. apollographql/react-apollo#1217
When using the cache-and-network
fetch policy I should be able to identify when I have data from the cache and when it is first retrieving the data.
<Query query={gql`{ now }` fetchPolicy="cache-and-network" notifyOnNetworkStatusChange>
{(data, error, networkStatus) => (
if (networkStatus < 4) return 'Loading'
if (error) return 'Error!'
return <div>
<time>data.now</time>
{networkStatus === 4 && 'Refeshing'}
</div>
)}
</Query>
_The query { now }
returns the current date and time._
I would expect networkStatus
to be 1
when it is making the first request, but 4
on each subsequent test as it is refetching the data.
Actual outcome:
Today the first request and subsequent requests come in using networkStatus = 1
making it difficult to identify the difference between the two states.
Versions
System:
OS: macOS Sierra 10.12.6
Binaries:
Node: 8.9.3 - ~/.nvm/versions/node/v8.9.3/bin/node
Yarn: 1.6.0 - ~/.nvm/versions/node/v8.9.3/bin/yarn
npm: 6.1.0 - ~/.nvm/versions/node/v8.9.3/bin/npm
Browsers:
Chrome: 67.0.3396.99
Firefox: 61.0
Safari: 11.1
This is quite similar to an issue I raised a while ago - I actually wrote a PR to address this, but it got lost in 2.0 limbo. It's definitely important to solve!
For anyone dealing with this PITA bug, an alternative is to use network-only
fetchPolicy. For whatever reason it functions exactly the same as cache-then-network
in my case, but reports correct network statuses.
@rtymchyk are you sure? With network-only
the cache is not considered, or it is bugged?
@all any news on this bug (FetchPolicy cache-and-network
always uses networkStatus = 1 regardless of cache hit)?
@frederikhors The network fetch happens with an explicit refetch only, which works well enough for me. Don't see much of an alternative 😢
@dallonf can you make a new smaller PR just for this problem in 2.0 land?
I'm not an Apollo maintainer, just a guy who wrote a (declined) PR once
@dallonf yes, I know. But maybe in that period there was a mess with 2.0 coming. Can you just re-write a smaller PR just for fix this? When you done I personally commit my time to assure it passes.
I could try, but I'm no more qualified than anybody else looking at this issue, and I don't have a lot of time to contribute to OSS at the moment, so if you really need this fixed ASAP, you're probably going to have to write the PR yourself.
It's also worth noting that my original PR(https://github.com/apollographql/apollo-client/pull/1607) isn't a "fix" - I diagnosed the problem as a gap in the design and added a whole new API to distinguish between two currently ambiguous states. This is something I really wouldn't be comfortable committing a lot of time developing until I have confirmation from the maintainers that this is a PR they would support; I don't want it to get ignored until the whole codebase changes out from under it again.
Same thing with broken cache-and-network
and variable changes, always 1
instead of 2
.
Somehow it works for me with network-only
which changes to 2
and still shows stale data in a component. 🤦♂️ 😆
Can someone confirm how this should work? I mean different network policies and how they affect response data and network status?
I'm seeing a similar issue. Basically, I make a query with cache-and-network
it returns it from the cache and sets the networkStatus
to 7
. It then makes the remote request and so the networkStatus
is set to 1
.
I tried to solve the issue by manually running markQueryResult()
for the said queries but they still didn't update. It seems to be some disconnect between the query manager and react-apollo.
I have a feeling this is the offending code As you can see the promise isn't return like the other fetch-policies. I tried a few things but couldn't get the networkStatus to update.
Any ideas?
Same thing with broken
cache-and-network
and variable changes, always1
instead of2
.Somehow it works for me with
network-only
which changes to2
and still shows stale data in a component.
For me, the networkStatus
returns same values for both cache-and-network
and network-only
.
Hopa this bug gets addressed soon. A comment from the maintainers would be nice just confirming it is a bug?!
I have the same issue. Only way to distinguish a cache hit is to use something like:
if (!data || (loading && !data.documents)) {
return <CardLoader />;
}
This is suboptimal because I cannot re-use this logic across different Query-components. Would prefer to have something like networkStatus=4
.
@hwillson any comments? Thanks!
Would be great to resolve this issue by either acknowledging that this is a bug and will be fixed, such that there's only a loading state when our cache is empty or introduce a non-breaking additive "cache-then-network" policy which does the above.
Would be nice to see this resolved so we can have reusable logic.
What's difference between cache-first
and cache-and-network
though ? These policies seems identical to me, so if it's better to remove the latter for not confusing users ?
@revskill10 With cache-first
if the data is found in the cache then no network request is made. cache-and-network
will return data from the cache but will also make a network request (even on a cache hit) and return updated data if available.
Is there a way (using cache-and-network) to do not update the cache if the data received after the network request is the same as the old one in the cache? Let's say i have a blog: the user enters in one article and it loads fast (since the data is in the cache); but if the autor of the artiche made some update, then apollo updates the relevant data, and react updates the relative component. Now it always update the cache, causing the unmounting and mounting again the various component, which is weird because the user sees a component with some data (the data from the cache) then it dissapear, and then appear again.
It's a bit concerning that this issue has had no attention from the team at all in 8 months.
A workaround to check wether data has been resolved from cache is to use isEmpty(data)
from lodash
or something similar.
We just published the final version of [email protected]
to npm, including the fix for this issue! See CHANGELOG.md
if you're curious about the other changes in this release.
Still not working for me. I do not think cache-and-network
is refetching therefore networkStatus
is never 4.
In a quick glance this should be be true if fetchPolicy
is cache-and-network
and there is something in the cache, no?
I'm running into the same issue as @antiold. with [email protected]
I see networkStatus
updating to in progress on initial load, but networkStatus
still isn't updating on a refetch
I can confirm that this is still an issue for me with Apollo-client 2.6.3 and a fetchPolicy of cache-and-network.
This is an issue for us as well. It looks like refetch
is trying to pull from the cache with cache-and-network
set as the fetch-policy. We were able to temporarily able to fix this by adding a dummy variable to the refetch
@benjamn I have created a simplified reproduction of this problem on Apollo client 2.6.4, which I think is still an issue. See:
https://codesandbox.io/s/apollo-cache-network-issue-miren
Notice that when you toggle the component which has the query back to visibility, it always goes from networkStatus 1 -> 7. Given the cache-and-network
fetchPolicy is used, shouldn't we be seeing it start at 4 during the cache hit and subsequent refetch? My expectation is that when the query component is shown for the 2nd time, that it will have a network status of 4 until the request finishes.
It seems like the concept of "refetch" is being used to describe the issue here, but I think the Apollo concept of "refetch" is not really applicable (literally calling refetch
). Instead, I think people are saying that when a query that has a cache-and-network
fetch policy is run for a second time (potentially through a re-render), there is no way to tell that the query is cached through the networkStatus
.
With that in mind, should I open a new issue?
This is a bit of an old issue, but it seems like it has the most relevant discussion.
I'm working on something at the moment where the view updates and I'm using cache-and-network to keep the interface feeling fast, while also being kept up-to-date.
I'm really struggling to figure out how to show loading states when I don't have cached data, but no loading state when I got data from the cache and Apollo is fetching the fresh data in the background. The problem is, when I don't have cached data, I still have the previous data returned from the hook, so I can't react to not having data, and loading is always true whenever it's loading either fresh data, or data in the background - so I can't use that either.
The closest I've come is reacting to when data changes, then comparing the new data with the old data to see if it's different, and if it's the same when loading is true then it must be the previous data. But it seems to bug out sometimes.
IMO what would be ideal is a different state when loading after data has been returned from the cache, so you could check loading === true and some network status that is something like "fetchingInBackground" (or maybe something more concise...)
I've forked @kylesuss reproduction using @apollo/client
3.1.3: https://codesandbox.io/s/apollo-cache-network-issue-ck662, the behavior is the same.
Most helpful comment
@benjamn I have created a simplified reproduction of this problem on Apollo client 2.6.4, which I think is still an issue. See:
https://codesandbox.io/s/apollo-cache-network-issue-miren
Notice that when you toggle the component which has the query back to visibility, it always goes from networkStatus 1 -> 7. Given the
cache-and-network
fetchPolicy is used, shouldn't we be seeing it start at 4 during the cache hit and subsequent refetch? My expectation is that when the query component is shown for the 2nd time, that it will have a network status of 4 until the request finishes.It seems like the concept of "refetch" is being used to describe the issue here, but I think the Apollo concept of "refetch" is not really applicable (literally calling
refetch
). Instead, I think people are saying that when a query that has acache-and-network
fetch policy is run for a second time (potentially through a re-render), there is no way to tell that the query is cached through thenetworkStatus
.With that in mind, should I open a new issue?