apollo-client: Query doesn't return empty entries from cached array (offset pagination) any more
We noticed that our implementation of an offset/limit bases pagination broke. This used to work with earlier Apollo Client 3.0 versions (beta/rc) but doesn’t work in 3.0.2.
Intended outcome:
Custom type policies should be able to merge pagination results . useQuery should return the array with the empty entries so that the component can find the data it needs to display a page based on an offset and limit.
Actual outcome:
The cache shows an array with empty entries. useQuery returns the array with the empty items removed.
Apollo Client 3.0.2 React 16.13.1
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 1
- Comments: 15 (6 by maintainers)
Hi @hwillson it is still a problem with latest. It would require an intentional update to reintroduce support for storing sparse arrays in Apollo cache. The current implementation uses a
filterarray operator that reduces a sparse array to a non-sparse array before storing.The downside to no longer supporting sparse arrays, as previously noted, is that it forces clients to pad their arrays with potentially millions of nulls before storing (imagine the case where only the first and thousandth page of data had been fetched, for example).
I just ran into this issue again while attempting to reconfigure pagination in my app. Respectfully, the provided
offsetLimitPaginationutility and documentation should be removed if it is not going to be updated as it simply does not work as the docs describe and has not worked for almost 3 years. It is quite frustrating to follow documentation exactly and have different results - something that over time leads to lost confidence in Apollo overall.The provided offsetLimitPagination policy no longer works properly as it creates sparse arrays that are now automatically filtered:
[0, 1, 2, <3 empty items>, 6]becomes[0, 1, 2, 6].I fixed this in our code by writing
nullin the cache and with a field read function:@benjamn @hwillson I think this should be clarified in the docs, you still have to patch the
readto make sure it doesn’t blow away empty slots in the array. Additionally, you can’tmapover sparse arrays like this:mapwill leave empty slots in the resulting array, but it does not call the callback function on them. To actually turn the empty slots intonull, you have to loop with afor:Further notes…the fix as suggested by @benjamn will not work in the case of sparse arrays (including the officially provided
offsetLimitPagintationutil) as the callback of a map function is not invoked for a sparse array “hole” (https://remysharp.com/2018/06/26/an-adventure-in-sparse-arrays).@cbergmiller workaround does work, but does suffer from the padding problem I mentioned in my previous comment, so does still feel to be like a workaround rather than an acceptable solution.