# Grouping keyArgs for pagination when using before and after cursor

**URL:** https://community.apollographql.com/t/grouping-keyargs-for-pagination-when-using-before-and-after-cursor/8872
**Category:** Client SDKs
**Tags:** caching, client
**Created:** [April 9, 2025, 10:39am UTC](https://community.apollographql.com/t/grouping-keyargs-for-pagination-when-using-before-and-after-cursor/8872 "2025-04-09T10:39:33Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![ookil](https://avatars.discourse-cdn.com/v4/letter/o/c0e974/32.png) [@ookil](https://community.apollographql.com/u/ookil)
#### Post date: [April 9, 2025, 10:39am UTC](https://community.apollographql.com/t/grouping-keyargs-for-pagination-when-using-before-and-after-cursor/8872/1 "2025-04-09T10:39:34Z")

</div>

Hello,  
I have run into an issue with caching when it comes to my pagination.  
my query accepts this args

```auto
query CatalogedPaints(
  $brandId: String
  $categoryId: String
  $color: PaintColor
  $search: String
  $after: String
  $before: String
  $perPage: Int
  $sortByColumn: SortField!
) {
  catalogedPaints(
    brandId: $brandId
    categoryId: $categoryId
    color: $color
    search: $search
    after: $after
    before: $before
    perPage: $perPage
    sortByColumn: $sortByColumn
  ) {
      ... fields 
     }

```

now i started with specifing keyArgs that are used for filtering

```auto
keyArgs: [
    'brandId',
     'categoryId',
     'color',
     'search',
     'sortByColumn',
],

```

this is working great, when for example `sortByColumn` changes query is cached in a separate entry, and i can get next page without an issue.

But problem is that my query uses cursor to specify sorting order, so `after` means desc order, and before is asc order. They can be undefined, null (initial sorting in given direction), have a string value = encoded cursor.  
Now, problem is if it’s possible to have two separate cache entries, one for using after and other for using before. I cannot specify both in keyArgs since this would cache each cursor separately.

I was almost able to solve this, by doing

```auto
const graphcache = new InMemoryCache({
    typePolicies: {
        Query: {
            fields: {
                catalogedPaints: {
                    keyArgs: (args) => {
                        if (args?.after !== undefined || !args?.before) {
                            return [
                                'brandId',
                                'categoryId',
                                'color',
                                'search',
                                'sortByColumn',
                                'before',
                            ];
                        }

                        return [
                            'brandId',
                            'categoryId',
                            'color',
                            'search',
                            'sortByColumn',
                            'after',
                        ];
                    },
                    merge(existing, incoming) {
                        return paginationMerge(existing, incoming);
                    },
                },
            },
        },
    },
});

```

and

```auto
const paginationMerge = (existing: any, incoming: any) => {
    if (!existing) {
        return incoming;
    }

    const mergedNodes = [...(existing?.nodes || [])];

    incoming?.nodes?.forEach((element: Reference) => {
        if (!mergedNodes.some(({ __ref }) =>__ref === element.__ref)) {
            mergedNodes.push(element);
        }
    });

    const result = {
        ...existing,
        ...incoming,
        nodes: mergedNodes,
    };

    return result;
};

```

but this only gives me

- Can paginate and merge results using after
- Can switch from after to before and see initial before results
- Can switch from before to after and see previously cached results

what im missing

- Merging results when using before. I have results for initial before: null, but then when i try to get next page with before: ‘someValue’ existing field shows me results that where cached when using after

Is there a way to make this work? Or do I need to have a separate argument for order direction instead of after/before?

---

<div class="post-metadata">

### Author: ![jerelmiller](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/jerelmiller/32/3314_2.png) [@jerelmiller](https://community.apollographql.com/u/jerelmiller)
#### Post date: [April 9, 2025, 5:36pm UTC](https://community.apollographql.com/t/grouping-keyargs-for-pagination-when-using-before-and-after-cursor/8872/2 "2025-04-09T17:36:52Z")

</div>

Hey @ookil 👋

Have you considered using a custom [`read` function](https://www.apollographql.com/docs/react/caching/cache-field-behavior#the-read-function)? `read` functions have access to all args on the field, so you might be able to implement the logic needed for the cursor/sorting in here. You can have your `read` function return `undefined` if your logic detects that it doesn’t have enough data to fulfill the data requirements and this will cause Apollo Client to fetch that query from the server.

Start by tinkering with a `read` function here to see if you’re able to remove that `before`/`after` cursor from `keyArgs`. Hope that helps!
