-
Notifications
You must be signed in to change notification settings - Fork 786
Set network status to 3 with cache-and-network fetch policy #1217
Comments
This issue has been automatically labled because it has not had recent activity. If you have not received a response from anyone, please mention the repository maintainer (most likely @jbaxleyiii). It will be closed if no further activity occurs. Thank you for your contributions to React Apollo! |
Hah @Stale take that, now I can label it myself! 🖕😆 (thanks @jbaxleyiii) This might've been fixed with the Apollo Client 2.0 rewrite which would be awesome, but I can't confirm that as we haven't had time to upgrade yet. |
Using Apollo Client 2.0, I can confirm that networkStatus is still 1 while using |
This issue has been automatically labled because it has not had recent activity. If you have not received a response from anyone, please mention the repository maintainer (most likely @jbaxleyiii). It will be closed if no further activity occurs. Thank you for your contributions to React Apollo! |
I can also confirm that the |
I am using a workaround until this is fixed. I am querying the cache to see if I have the result cached, if that is the case I don't render the loading spinner: <Query query={query} fetchPolicy="cache-and-network">
{({ loading, error, data, client, variables }) => {
const { complete } = client.cache.diff({
query: client.cache.transformDocument(query),
variables,
returnPartialData: true,
optimistic: false
});
if (!complete && loading) return <Loading/>;
if (error) return <Error error={error}/>;
return <div>Render data {data}</div>;
}}
</Query> |
+1 Rendering a Loading component on networkStatus = 1 makes cache-and-network completely useless, behavior is the same as network-only... |
I feel like |
No news on this, right? Is there a workaround until resolution? |
I have found another funny workaround for the problem:
fetch policy can be either cache-and-network or network-only |
@andrei-zhaleznichenka is this better than this: #1217 (comment)? |
@mxstbr any news about this? About |
+1 |
Blindly setting networkStatus to NetworkStatus.loading after the client part of a cache-and-network query was destroying useful information about the status of the request. Instead, we should use NetworkStatus.ready only when the request is complete, and leave networkStatus untouched otherwise. Fixes #3660, #4693, and apollographql/react-apollo#1217.
Blindly setting networkStatus to NetworkStatus.loading after the client part of a cache-and-network query was destroying useful information about the status of the request. Instead, we should use NetworkStatus.ready only when the request is complete, and leave networkStatus untouched otherwise. Fixes #3660, #4693, and apollographql/react-apollo#1217.
This was addressed in apollographql/apollo-client#4765, and the fix is available in |
@hwillson Has anyone confirmed that this is working? I still see |
@declanelcocks Any chance you can put together a small runnable reproduction using 2.5.6? |
@hwillson A bit difficult for me to create a runnable reproduction at the moment since it's part of a large app. But anyway, if I log a few things when a 1. { networkStatus: 7, complete: true, loading: false }
2. { networkStatus: 1, complete: true, loading: true }
3. { networkStatus: 7, complete: true, loading: false } I'm getting const cache = result.client.cache.diff({
query: result.client.cache.transformDocument(this.props.query),
variables: this.props.variables,
returnPartialData: true,
optimistic: false
}); My current workaround, as I've seen in older issue threads, is to do the following:
There's more to it, but you get the gist. I got the idea from here and also from #2601 where people came to similar solutions. This is with |
Does not work for me as well. I’ve created a repo reproducing the problem: https://github.com/marek-saji/react-apollo-1217 using starwars-server. |
@hwillson Here is another minimal reproduction: https://codesandbox.io/s/apollo-cache-network-issue-miren Using |
Seems like this is still an issue as per @kylesuss's reproduction - any news regarding this? |
Using hooks: import { useQuery } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const query = gql` ... `;
const variables = { ... };
const { loading, error, data, client } = useQuery(query, {
variables,
fetchPolicy: 'cache-and-network',
};
// Query the cache
let inCache = true;
if (loading) {
try {
client.readQuery({ query, variables }); // Read from cache. Error thrown if empty
} catch {
inCache = false;
}
}
return (loading && !inCache) ? <Loading /> : <Data />; |
Based on previous solutions/workarounds, I have made a custom hook for this situation: // useApolloCacheQuery.ts
import { useApolloClient } from '@apollo/react-hooks'
import { OperationVariables } from 'apollo-boost'
import { Cache } from 'apollo-cache'
import { DocumentNode } from 'graphql'
/** Custom hook to query the cache to determine if query result exists already */
export default function useApolloCacheQuery<T>(
query: DocumentNode,
variables: OperationVariables,
): Cache.DiffResult<T> {
const { cache } = useApolloClient()
return cache.diff({
query: cache.transformDocument(query),
variables,
returnPartialData: true,
optimistic: false,
})
} // Component.tsx
// ..
const { data, loading } = useQuery<DataResponse>(query, {
variables,
})
const { complete } = useApolloCacheQuery(query, variables)
return (!complete && loading) ? <Loader /> : <Child />;
// .. |
Can we reopen this case? |
Still having issues here as well ! Right now you cant really follow the stale-while-revalidate pattern, which makes |
Let's reopen it, I want to use SWR too! |
I wrote two custom hooks that are wrappers around They simply do what @sincospi said: check the cache and set loading to true if it didn't find an entry. I found this to be the solution with less refactoring needed. |
Intended outcome:
I want to show my users that the app is loading fresh data in the background when they get a render from the cache. (i.e.
fetchPolicy
is set tocache-and-network
) In our app, this mostly happens when users navigate back to a page they've been on previously and we render the data from the cache first, while usingcache-and-network
to load fresh data from the server.Actual outcome:
I can't do that because
networkStatus
does not expose that information.Idea:
Rather than
networkStatus
3 being specific tothis.props.data.refetch()
, why not also set thenetworkStatus
to 3 when the data is refetched by thecache-and-network
fetch policy? The data is being refetched (even if not by callingrefetch()
) so it makes sense for thenetworkStatus
to reflect that reality.The text was updated successfully, but these errors were encountered: