apollographql / apollo-client

:rocket:  A fully-featured, production ready caching GraphQL client for every UI framework and GraphQL server.
https://apollographql.com/client
MIT License
19.4k stars 2.66k forks source link

"OnCompleted" called not called after "fetchMore" #9151

Open jeremy303 opened 3 years ago

jeremy303 commented 3 years ago

(If this should move to StackOverflow, just let me know. )

Intended outcome:

I'm trying to recursively fetch all pages of a query's results by executing fetchMore in my onCompleted handler.

  const {
    loading,
    error,
    data,
    fetchMore,
  } = useQuery(
    GET_EXAMPLE_QUERY,
    {
      variables: { someFilter },
      onCompleted: (d) => {
        const { hasNextPage, endCursor } = d.allExamples.pageInfo;
        console.log(`onCompleted: hasNextPage=${hasNextPage}, endCursor=${endCursor}`);
        if (hasNextPage) {
          fetchMore({
            variables: {
              after: endCursor,
            },
          });
        }
      },
    },
  );

The example query:

query GetExamples($after: String, $someFilter: String) {
  allExamples(
    after: $after,
    where: { someFilter: $someFilter },
    sortBy: meta_lastPublicationDate_DESC,
  ) {
    totalCount
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      cursor
      node {
        _meta {
          id
        }
        status
      }
    }
  }
}

The server uses Relay-style pagination, so I'm using the relayStylePagination helper:

new ApolloClient({
    ...
    cache: new InMemoryCache({
      typePolicies: {
        Query: {
          fields: {
            allExamples: relayStylePagination(),
          },
        },
      },
    }),
  });

Actual outcome:

onCompleted is only called once when the first page is loaded, but not after fetchMore, resulting in only the first two pages being fetched.

How to reproduce the issue:

(If needed, I can create a reproduction of the error)

Versions

  System:
    OS: macOS 11.6.1
  Binaries:
    Node: 10.22.0 - ~/.nvm/versions/node/v10.22.0/bin/node
    npm: 6.14.9 - ~/.nvm/versions/node/v10.22.0/bin/npm
  Browsers:
    Chrome: 96.0.4664.55
    Firefox: 84.0.1
    Safari: 14.1.2
  npmPackages:
    @apollo/client: ^3.4.5 => 3.4.5 
    @apollo/react-ssr: ^4.0.0 => 4.0.0 
    apollo-link-prismic: ^1.0.9 => 1.0.9 
phaoga54 commented 2 years ago

I'm facing the same issue. When I call fetchMore with increased page, checking in the network, it still return the correct result, but onCompleted doesn't give me anything.

camhammel commented 2 years ago

I'm experiencing a similar issue - the fetchMore call is completing on the network side, but the Promise it returns is never resolved or rejected. This also is preventing the data itself from updating as a result.

mogelbrod commented 2 years ago

Having the same issue - right now I pretty much have to conditionally trigger a fetchMore() in the render loop to ensure that the remaining pages (after the second one) gets loaded.

TheAdamBorek commented 2 years ago

I think when you set notifyOnNetworkStatusChange: true then onCompleted will be called after fetchMore.

mogelbrod commented 2 years ago

I think when you set notifyOnNetworkStatusChange: true then onCompleted will be called after fetchMore.

It will also trigger re-renders on every network status change, which is rather undesirable 😐

alex-golubtsov commented 9 months ago

Looks like the issue is pretty old https://github.com/apollographql/react-apollo/issues/3709

Any progress?

hngu commented 2 months ago

Still have the same issue here as well. Is there any plan to fix this? Is this suppose to work this way?