You are viewing documentation for a preview version of this software.

Learn about previews.

Pagination support in the normalized cache


The normalized cache includes support for pagination, allowing you to merge pages of data into the same record field. This allows your application to watch a query for a list of items, receive updates when new pages are fetched, and update the UI with the full list.

Keep reading to learn more about pagination in the context of a normalized cache.

Pagination with a normalized cache

When using the normalized cache, objects are stored in records keyed by the object's id:

Query:

GraphQL
1query Users {
2  allUsers(groupId: 2) {
3    id
4    name
5  }
6}

Response:

JSON
1{
2  "data": {
3    "allUsers": [
4      {
5        "id": 1,
6        "name": "John Smith"
7      },
8      {
9        "id": 2,
10        "name": "Jane Doe"
11      }
12    ]
13  }
14}

Normalized cache:

Cache KeyRecord
QUERY_ROOTallUsers(groupId: 2): [ref(user:1), ref(user:2)]
user:1id: 1, name: John Smith
user:2id: 2, name: Jane Doe

The app can watch the Users() query and update the UI with the whole list when the data changes.

However with pagination things become less obvious:

Query:

GraphQL
1query UsersPage($page: Int!) {
2  usersPage(groupId: 2, page: $page) {
3    id
4    name
5  }
6}

Response:

JSON
1{
2  "data": {
3    "usersPage": [
4      {
5        "id": 1,
6        "name": "John Smith"
7      },
8      {
9        "id": 2,
10        "name": "Jane Doe"
11      }
12    ]
13  }
14}

Normalized cache:

Cache KeyRecord
QUERY_ROOTusersPage(groupId: 2, page: 1): [ref(user:1), ref(user:2)]
user:1id: 1, name: John Smith
user:2id: 2, name: Jane Doe

After fetching page 2, the cache will look like this:

Cache KeyRecord
QUERY_ROOTusersPage(groupId: 2, page: 1): [ref(user:1), ref(user:2)],
usersPage(groupId: 2, page: 2): [ref(user:3), ref(user:4)]
user:1id: 1, name: John Smith
user:2id: 2, name: Jane Doe
user:3id: 3, name: Peter Parker
user:4id: 4, name: Bruce Wayne

Which query should the app watch to update the UI?

Watching UsersPage(page = 1) would only notify changes to the first page.

For the whole list to be reactive you'd need to watch the queries for each page, and update the corresponding segment of the list. While technically possible, this is cumbersome to implement.

You could skip watching altogether and only update the list when scrolling to its end, but that would mean that changes to individual items would not be reflected in the list UI.

What we need is having the whole list in a single field, so we can watch a single query.

Feedback

Edit on GitHub

Ask Community