Hello,
I have run into an issue with caching when it comes to my pagination.
my query accepts this args
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
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
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
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?