So I have an app with React, GraphQL and urql. I have a query that returns data (called readMeanings
), and I have pagination (with a "Load more" button).
The problem is this: because of my pagination, when I reverse the sorting (from DESC
to ASC
), the sorted data is appended to what I had before, kind of like the "Load more" button is supposed to work.
The data looks like this (it would show 1 2 3
after 10 9 8
when I click "Load more"):
DESC: | ASC:
10 | 10
9 | 9
8 | 8
("Load more")
7 | 1
6 | 2
5 | 3
When I delete my cache pagination logic, it displays correctly as 1 2 3
, but I obviously want to keep the pagination.
I'm using an urql's local resolver for the pagination cache update:
resolvers: {
Query: {
readMeanings: cursorMeaningPagination(),
},
},
The query readMeanings
accepts limit
, cursor
, used for pagination, and sorting
(which contains orderBy
, basically SQL's ORDER BY
). These inputs are included in the field keys for different versions of the readMeanings
query fields (see below). The query returns hasMore
, which is used to hide/show the "Load more" button and meanings
, which are the Meaning
records themselves.
On the server side, changing orderBy
works correctly.
My cache update logic is this (taken from Ben Awad's fullstack tutorial, around 7h 14m):
const cursorMeaningPagination = (): Resolver => {
return (_parent, fieldArgs, cache, info) => {
const { parentKey: entityKey, fieldName } = info; // entityKey is a query, fieldName is readMeanings
const allFields = cache.inspectFields(entityKey); // This gives us all queries
const fieldInfos = allFields.filter((info) => info.fieldName === fieldName); // This gives us all readMeanings queries in cache
const size = fieldInfos.length;
if (size === 0) {
return undefined;
}
const fieldKey = `${fieldName}(${stringifyVariables(fieldArgs)})`;
const isInCache = cache.resolve(
cache.resolve(entityKey, fieldKey) as string,
"meanings"
); // If given query is in cache
let hasMore = true;
const results: string[] = [];
info.partial = !isInCache; // Do partial return if not in cache
// For each particular cached query that we care about
fieldInfos.forEach((fi) => {
const key = cache.resolve(entityKey, fi.fieldKey) as Entity; // Get query's field key (includes specific args)
const data = cache.resolve(key, "meanings") as string[]; // key like: 'posts({"limit":10})'
const _hasMore = cache.resolve(key, "hasMore");
if (!_hasMore) {
hasMore = _hasMore as boolean; // If _hasMore is false
}
results.push(...data);
});
return { __typename: "PaginatedMeanings", hasMore, meanings: results };
};
};
I see that data
is taken from the cache, and appended to results
, and those are meanings
.
This must be really simple, but I can't guess what exactly I have to do to.
Any help would be appreciated!