apollo-client icon indicating copy to clipboard operation
apollo-client copied to clipboard

fetchMore networkStatus and notifyOnNetworkChange not working in 3.3.7

Open robertsmit opened this issue 4 years ago • 16 comments

In the latest version (3.3.7) the networkStatus for fetchingMore is not working:

export declare enum NetworkStatus {
    loading = 1,
    setVariables = 2,
    fetchMore = 3,
    refetch = 4,
    poll = 6,
    ready = 7,
    error = 8
}

But when calling fetchMore, the networkStatus is never changed to 3 when notifyOnNetworkChange = true....

robertsmit avatar Jan 22 '21 08:01 robertsmit

@robertsmit Could you provide a runnable reproduction using either this repo or this CodeSandbox?

jcreighton avatar Feb 05 '21 15:02 jcreighton

I'm seeing the same ... I'm expecting that if a call to fetchMore triggers a network call, then either loading or networkStatus should be updated so I can let the user know that data is loading.

I have a query setup like this:

const { loading, error, data, fetchMore, networkStatus } = useQuery(ALL_JOBS, {
    variables: {
      filter,
      first: rowsPerPage,
      sortBy,
      sortDir,
    },
    notifyOnNetworkStatusChange: true,
    context: {
      debounceKey: "ALL_JOBS",
      debounceTimeout: 50,
    },
  })

Then I have a sort function that gets called when a user wants to change the sorting:

function sort(propertyName) {
    const newSortBy = propertyName
    const newSortDir = propertyName !== sortBy ? "ASC" : sortDir === "ASC" ? "DESC" : "ASC"
    setSortBy(newSortBy)
    setSortDir(newSortDir)
    setPage(0)
    fetchMore({
      variables: {
        filter,
        first: rowsPerPage,
        sortBy: newSortBy,
        sortDir: newSortDir,
      },
    })
  }

I can see that this triggers a network call, but the loading always remains false and networkStatus always stays at 7.

This query is configured to use the relayStylePagination from @apollo/client/utilities, btw

sflahave avatar Feb 14 '21 00:02 sflahave

I'm seeing the same issue. I'm using local-only fields in my query and when my local-only fields change, it refetches from the network, but does not update the loading and networkStatus variables.

ramiAbdou avatar Apr 27 '21 17:04 ramiAbdou

Any update on this. We are also facing the same issue.

chyamuna avatar Jan 06 '22 13:01 chyamuna

+1

eyalw avatar Feb 20 '22 11:02 eyalw

+1

Its always the same ===7

alex20465 avatar Mar 15 '22 13:03 alex20465

I don't believe this issue needs reproduction. The scenario described is pretty common, no?

drewlustro avatar Jul 06 '22 21:07 drewlustro

I'm having the same problem and came across this issue while searching and can't believe it's still open so I'll add my situation to the list too.

Code is simplified for a better reading experience

Given the query:

const query = gql`
  query fetchSomeData($skip: Int!, $take: Int!) {
    items(skip: $skip, first: $take) {
      id
      title
    }
}`

In my component:

const Component = () => {
  const skip = useRef(0);
  const {data, loading, fetchMore} = useQuery(query, {
    notifyOnNetworkStatusChange: true // having this does not make any difference
    variables: {
      skip: skip.current,
      take: 10
    }
  })

  return (
    <div>
      {loading && <Spinner />}
      {data.items.map(item => <ItemRenderer item={item} />)}
      <button onClick={() => fetchMore({ variables: { skip: skip.current + 10 } })}>Load more</button>
    </div>
  )
}

Clicking the button triggers the network request, and data gets updated but loading never changes. I have a very basic, naive array merge policy in the cache configuration like the one below:

typePolicies: {
  Query: {
          fields: {
            items: {
              keyArgs: false,
              merge(existing = [], incoming) {
                return [...existing, ...incoming];
              },
            },
          },
        }
}

If I remove the field policy then I need to provide a similar merge policy in the updateQuery parameter of fetchMore but regardless the loading field from the useQuery result never gets updated.

alaminut avatar Dec 21 '22 14:12 alaminut

Also, just wanted to add that I am seeing the same behaviour as mentioned by @alaminut

dhmcloud avatar Feb 13 '23 20:02 dhmcloud

This should solve the issue.

bhavikagrawal avatar Feb 21 '23 10:02 bhavikagrawal

This should solve the issue.

Unfortunately it didn't solve the problem for me. I don't set the query and have the same problem. My code is like below:

const handleLoadMoreClick = () => {
    //setLoadMoreLoading(true);
    const endCursor = data?.liveData?.pageInfo.endCursor;
    fetchMore({
      variables: { after: endCursor },
      updateQuery: (previousQueryResult, { fetchMoreResult }) => {
        if (!fetchMoreResult.liveData) return previousQueryResult;
        fetchMoreResult.liveData.edges = [
          ...(previousQueryResult.liveData?.edges?.map((x) => x) ?? []),
          ...(fetchMoreResult.liveData.edges ?? []),
        ];
        //setLoadMoreLoading(false);
        return fetchMoreResult;
      },
    });
  };

The commented lines are a workaround for setting loading state for a button. I use "@apollo/client": "^3.6.6"

miladdotnetdeveloper avatar Feb 21 '23 10:02 miladdotnetdeveloper

This should solve the issue.

Unfortunately it didn't solve the problem for me. I don't set the query and have the same problem. My code is like below:

const handleLoadMoreClick = () => {
    //setLoadMoreLoading(true);
    const endCursor = data?.liveData?.pageInfo.endCursor;
    fetchMore({
      variables: { after: endCursor },
      updateQuery: (previousQueryResult, { fetchMoreResult }) => {
        if (!fetchMoreResult.liveData) return previousQueryResult;
        fetchMoreResult.liveData.edges = [
          ...(previousQueryResult.liveData?.edges?.map((x) => x) ?? []),
          ...(fetchMoreResult.liveData.edges ?? []),
        ];
        //setLoadMoreLoading(false);
        return fetchMoreResult;
      },
    });
  };

The commented lines are a workaround for setting loading state for a button. I use "@apollo/client": "^3.6.6"

Did you use notifyOnNetworkStatusChange: true ?

bhavikagrawal avatar Feb 21 '23 11:02 bhavikagrawal

I'm having the same issue. Setting notifyOnNetworkStatusChange to true doesn't solve it. After ajax call ends, the values of loading and networkStatus are always set to true and 3 ( fetchMore ) respectively.

SimplySayHi avatar Feb 22 '23 16:02 SimplySayHi

This should solve the issue.

Unfortunately it didn't solve the problem for me. I don't set the query and have the same problem. My code is like below:

const handleLoadMoreClick = () => {
    //setLoadMoreLoading(true);
    const endCursor = data?.liveData?.pageInfo.endCursor;
    fetchMore({
      variables: { after: endCursor },
      updateQuery: (previousQueryResult, { fetchMoreResult }) => {
        if (!fetchMoreResult.liveData) return previousQueryResult;
        fetchMoreResult.liveData.edges = [
          ...(previousQueryResult.liveData?.edges?.map((x) => x) ?? []),
          ...(fetchMoreResult.liveData.edges ?? []),
        ];
        //setLoadMoreLoading(false);
        return fetchMoreResult;
      },
    });
  };

The commented lines are a workaround for setting loading state for a button. I use "@apollo/client": "^3.6.6"

Did you use notifyOnNetworkStatusChange: true ?

Thank you for reply, I set the option notifyOnNetworkStatusChange: true in useQuery and it seems networkStatus != NetworkStatus.ready is reliable now.

miladdotnetdeveloper avatar Feb 22 '23 21:02 miladdotnetdeveloper

I'm having the same issue. Setting notifyOnNetworkStatusChange to true doesn't solve it. After ajax call ends, the values of loading and networkStatus are always set to true and 3 ( fetchMore ) respectively.

loading will always result to true for fetchmore, therefor you need to use networkStatus to toggle your loading state.

bhavikagrawal avatar Feb 23 '23 06:02 bhavikagrawal

This should solve the issue.

Awesome thanks, this worked for us, we were passing the query property to fecthMore. removed it and voila!

fridaystreet avatar Aug 14 '24 01:08 fridaystreet