Skip to content
This repository has been archived by the owner on Apr 13, 2023. It is now read-only.

Set network status to 3 with cache-and-network fetch policy #1217

Closed
mxstbr opened this issue Oct 8, 2017 · 26 comments
Closed

Set network status to 3 with cache-and-network fetch policy #1217

mxstbr opened this issue Oct 8, 2017 · 26 comments
Assignees
Labels
bug-upstream Bug confirmed to originate from a dependency in-progress

Comments

@mxstbr
Copy link

mxstbr commented Oct 8, 2017

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 to cache-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 using cache-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 to this.props.data.refetch(), why not also set the networkStatus to 3 when the data is refetched by the cache-and-network fetch policy? The data is being refetched (even if not by calling refetch()) so it makes sense for the networkStatus to reflect that reality.

@stale
Copy link

stale bot commented Oct 29, 2017

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!

@mxstbr
Copy link
Author

mxstbr commented Oct 29, 2017

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.

@taikn
Copy link

taikn commented Nov 12, 2017

Using Apollo Client 2.0, I can confirm that networkStatus is still 1 while using cache-and-network fetch policy.

@stale
Copy link

stale bot commented Dec 3, 2017

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!

@tdeekens
Copy link

tdeekens commented Feb 5, 2018

I can also confirm that the networkStatus is always alternating between 1 and 7 when having the fetchPolicy set to cache-and-network. Is there anyway around having a loading spinner show when for a subsequent fetch? Did anyone find a solution to this?

@axelhzf
Copy link

axelhzf commented May 17, 2018

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>

@bl42
Copy link

bl42 commented Jun 18, 2018

+1
Please add a different networkStatus to cache-and-network when the data is in the cache.

Rendering a Loading component on networkStatus = 1 makes cache-and-network completely useless, behavior is the same as network-only...

@nrdobie
Copy link

nrdobie commented Jul 5, 2018

I feel like networkStatus should equal 4 as it is essentially doing a refetch.

@frederikhors
Copy link

No news on this, right? Is there a workaround until resolution?

@pan-kot
Copy link

pan-kot commented Oct 23, 2018

I have found another funny workaround for the problem:

<Query query={query} fetchPolicy="cache-and-network">
  {(networkQuery) => (
    <Query query={query}>
      {(cacheQuery) => {
        if (networkQuery.loading && ! cacheQuery.loading) return <ReLoading />;
        if (cacheQuery.loading) return <Loading />;
        if (error) return <Error error={error}/>;
        return <Data />;
    }}
    </Query>
  )}
</Query>

fetch policy can be either cache-and-network or network-only

@frederikhors
Copy link

@andrei-zhaleznichenka is this better than this: #1217 (comment)?

@frederikhors
Copy link

@mxstbr any news about this? About cache-and-network status code in networkStatus? Still nothing or did I miss some news?

@fgiarritiello
Copy link

+1

@benjamn benjamn self-assigned this Apr 30, 2019
benjamn added a commit to apollographql/apollo-client that referenced this issue Apr 30, 2019
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.
benjamn added a commit to apollographql/apollo-client that referenced this issue Apr 30, 2019
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.
@benjamn benjamn added bug-upstream Bug confirmed to originate from a dependency in-progress and removed bug labels Apr 30, 2019
@hwillson
Copy link
Member

This was addressed in apollographql/apollo-client#4765, and the fix is available in react-apollo 2.5.6. Thanks!

@declanelcocks
Copy link

@hwillson Has anyone confirmed that this is working? I still see networkStatus: 1 all the time when the network kicks in despite complete being true.

@hwillson
Copy link
Member

@declanelcocks Any chance you can put together a small runnable reproduction using 2.5.6?

@declanelcocks
Copy link

declanelcocks commented Jun 26, 2019

@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 cache-and-network query loads, I will get:

1. { networkStatus: 7, complete: true, loading: false }
2. { networkStatus: 1, complete: true, loading: true }
3. { networkStatus: 7, complete: true, loading: false }

I'm getting complete from this (as above):

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:

const showCache =
  this.props.fetchPolicy !== 'network-only' &&
  this.props.fetchPolicy !== 'no-cache' &&
  cache.complete;

const loading = showCache ? false : result.loading

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 [email protected].

marek-saji added a commit to marek-saji/react-apollo-1217 that referenced this issue Jul 26, 2019
@marek-saji
Copy link

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.

image

@kylesuss
Copy link

kylesuss commented Sep 24, 2019

@hwillson Here is another minimal reproduction:

https://codesandbox.io/s/apollo-cache-network-issue-miren

Using apollo-client 2.6.4.

@MYKEU
Copy link

MYKEU commented Oct 9, 2019

Seems like this is still an issue as per @kylesuss's reproduction - any news regarding this?

@sincospi
Copy link

sincospi commented Dec 19, 2019

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 />;

@MYKEU
Copy link

MYKEU commented Feb 27, 2020

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 />;
// ..

@damiangreen
Copy link

Can we reopen this case?

@austinh
Copy link

austinh commented Apr 3, 2020

Still having issues here as well ! Right now you cant really follow the stale-while-revalidate pattern, which makes cache-and-network completely useless. 😭

@arvindell
Copy link

Let's reopen it, I want to use SWR too!

@arvindell
Copy link

I wrote two custom hooks that are wrappers around useQuery and useLazyQuery and rewrite the loading property in order to enable this behavior. You can find them here: https://gist.github.com/alexvilchis/64a5b07172e8e216c6542f4f4b637cdd

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug-upstream Bug confirmed to originate from a dependency in-progress
Projects
None yet
Development

No branches or pull requests