Description
Describe the bug
Apollo 3 recommends using InMemoryCache typePolicies
for cache operations for pagination instead of updateQuery
on the fetchMore function.
When trying to use typePolicies with vue-apollo, the behaviour is not as intended.
To Reproduce
Steps to reproduce the behavior:
- Create Apollo Client using an InMemoryCache which has some typePolicies for the paginated query (define merge and read functions)
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
paginatedField: {
keyArgs: ['filter'],
merge (existing = makeEmptyPaginatedData(), incoming, { args: { page = 0, count = 10 } }) {
console.log('merge options:', page, count, 'data:', incoming);
const start = page * count;
const merged = existing.items.slice(0);
for (let i = 0; i < incoming.items.length; ++i) {
merged[start + i] = incoming.items[i];
}
return Object.assign({}, incoming, {
items: merged,
index: existing.index !== -1 && existing.index < incoming.index ? existing.index : incoming.index,
count: merged.length,
hasPrevious: start > 0 ? existing.hasPrevious : incoming.hasPrevious,
hasNext: start + count < merged.count ? existing.hasNext : incoming.hasNext,
});
},
read (existing, { args: { page = 0, count = 10 } }) {
if (!existing) {
return;
}
const start = page * count;
const end = start + count;
const items = existing.items.slice(start, end);
const result = Object.assign({}, existing, {
items,
index: page,
count: items.length,
hasPrevious: page > 0,
hasNext: existing.items.length > end || existing.hasNext,
});
console.log('read options:', page, count, 'data:', result);
return result;
},
},
},
},
},
});
- Define paginated query
const { result, fetchMore } = useQuery(
gql`query ($page: Int, $count: Int) {
paginatedField(filter: [...], page: $page, count: $count) {
index
count
hasPrevious
hasNext
items {
[...]
}
}
}`,
{
page: 0,
count: 10,
},
);
- Load page (initial query ran with variables page=0, count=10)
- Call fetchMore with variables page=1, count=10
- Console output:
merge options: 0 10 data: [...]
read options: 0 10 data: [...]
// here fetchMore is called
merge options: 1 10 data: [...]
read options: 0 10 data: [...]
Expected behavior
Read function should be called with variables from most recent query (e.g. fetchMore call) just like merge function is called
Console would read as follows:
merge options: 0 10 data: [...]
read options: 0 10 data: [...]
// here fetchMore is called
merge options: 1 10 data: [...]
read options: 1 10 data: [...]
Versions
vue: 2.6.12
vue-apollo: @vue/[email protected]
apollo-client: 3.3.18
Additional context
Add any other context about the problem here.
Research guided me towards this Apollo issue, however I could not figure out how to apply this to solve my problem.
#1115 also seems to be similar, but didn't provide a clear solution either.