Angular graphql Apollo pagination
Asked Answered
D

1

6

Could someone provide an example of pagination implemented with Apollo Client 3.0 Field Policies. I've been following the example from the docs to implement infinite scroll but in my console I'm getting the following warning:

The updateQuery callback for fetchMore is deprecated, and will be removed in the next major version of Apollo Client.

Please convert updateQuery functions to field policies with appropriate read and merge functions, or use/adapt a helper function (such as concatPagination, offsetLimitPagination, or relayStylePagination) from @apollo/client/utilities.

The field policy system handles pagination more effectively than a hand-written updateQuery function, and you only need to define the policy once, rather than every time you call fetchMore.

So I was tried to implement pagination with a new Apollo approach

list.component.ts

// getOffers() is run in OnInit()

  getOffers(): void {
    this.searchService.search
      .pipe(
        tap(() => {
          this.spinnerService.showLoader();
        }),
        switchMap((term) => {
          this.lookupTerm = term;
          return this.offersGQL.watch({
            phrase: term,
            offset: this.pageOffset,
            limit: this.pageSize
          }, { fetchPolicy: 'network-only' })
            .valueChanges
            .pipe(
              retry(40),
              map((result) => result.data),
              tap(() => {
                this.spinnerService.hideLoader();
              })
            )
        }
        )
      )
      .subscribe((result) => {
        this.offers = result.offers.items;
      })
  }

// fetchMore()

  fetchMore() {
    this.offersGQL.watch({
      phrase: this.lookupTerm,
      offset: this.pageOffset,
      limit: this.pageSize
    },
      { fetchPolicy: 'network-only' }
    ).fetchMore({
      variables: {
        offset: this.offers.length,
      }
      // updateQuery: (prev, { fetchMoreResult }) => {
      //   console.log([...prev.offers.items, ...fetchMoreResult.offers.items]);

      //   if (!fetchMoreResult) { return prev; }
      //   return Object.assign({}, prev, {
      //     offers: [...prev.offers.items, ...fetchMoreResult.offers.items],
      //   });
      // }
    })

  }

// graphql.module

  const cache = new InMemoryCache({
    typePolicies: {
      Query: {
        fields: {
          // Keep searches separated by args.query (but not by any other
          // arguments, since the field policy will handle them).
          offers: offsetLimitPagination(),
        },
      },
    },
  });

Now, when I remove part with the typePolicies from InMemoryCache then my offers list is loaded but fetchMore() will not return anything. With typePolicies neither list is loaded nor fetchMore() works. Could someone please provide me with the correct way to make pagination working?

Dissert answered 8/10, 2020 at 7:47 Comment(0)
T
0

Had the same problem today.

All you have to do: After the .fetchMore() add .then() and inside it call the updateQuery() method on the QueryRef.

But first you need to separate the QueryRef into another prop.

Like this:

  watchOffersQueryRef = 
    this.offersGQL.watch({
      phrase: this.lookupTerm,
      offset: this.pageOffset,
      limit: this.pageSize
    },
    { fetchPolicy: 'network-only' }
    );

  fetchMore() {
    this.watchOffersQueryRef.fetchMore({
      variables: {
        offset: this.offers.length,
      }
    }).then((fetchMoreResult) => {
       this.watchOffersQueryRef.updateQuery(prev) => {
         if (!fetchMoreResult) { return prev; }
         return Object.assign({}, prev, {
           offers: [...prev.offers.items, ...fetchMoreResult.offers.items],
         });
       }
    })
  }
Thury answered 29/8, 2024 at 13:30 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.