Using Pagination and FetchMore with Apollo-Angular GraphQL Client

171 Views Asked by At

I am trying to use an offset-limit model to fetch more data in an infinite scroll. Right now my initial query contains duplicate data and the refetch call simply emits the same data. My server responds as expected to all the actual requests.

Does anyone know how I am supposed to implement pagination with fetchMore in apollo-angular or why this behavior seems so irregular?

app.module.ts

cache: new InMemoryCache({
  typePolicies: {
    Query: {
      fields: {
        myFriends: offsetLimitPagination(),  // without this, the initial query fetches the right data but fetchMore() doesn't cause the observable to be hit
        // I have tried playing around with read() and merge() here unsuccessfully
      }
    }
  }
})

queries.ts

export const myFriendsQuery = gql`
query MyFriends($limit: Int, $offset: Int, $search: String, $orderBy: [Sort!]) {
  myFriends(limit: $limit, offset: $offset, search: $search, orderBy: $orderBy) {
    uid
    username
  }
}
`;

friend.service.ts

getFriends(limit?: number, offset?: number, search?: string, sort?: Sort[]) {
  return this.apollo.watchQuery<{ myFriends: User[] }>({
    query: myFriendsQuery,
    variables: {
      limit: limit,
      offset: offset,
      search: search,
      orderBy: sort,
    },
    fetchPolicy: 'network-only',
  });
}

friends.component.ts

ngOnInit() {
  this.query = this.friendService.getFriends(10, 0, "", [{ firstName: 'ASC' }]);

  this.query.valueChanges.subscribe({
    next: value => {
      this.friends = value.data.myFriends; // this has an array length of 12 despite the network tab clearly showing a response of 10 length array
      
      // 2 of the response objects are duplicated, seemingly at random
      // if I remove the offsetLimitPagination() cache configuration, this behaves as expected

      // after fetchMore() is called, this method is called again with the exact same 12 data values
      // but the network tab clearly shows a graphql request firing that responds with the correct next data sequence
      // if offsetLimitPagination() is removed, this subscription will not be called
    }
  });
}

handleInfiniteScroll(event: Event) {
  this.offset += 10;
  this.query.fetchMore({
    variables: {
      limit: 10,
      offset: this.offset,
    },
  });
}
1

There are 1 best solutions below

0
On

lol, it looks like I simply needed to define my additional key arguments in the offsetLimitPagination configuration, since I am using search and orderBy parameters as well. Literally the next section in the docs...

fields: {
  myFriends: offsetLimitPagination(['search', 'orderBy']),
}