My problem is that pagination for some reason does not work, most likely due to the fact that existing in this file = undefined
import { FieldPolicy } from "@apollo/client/cache/inmemory/policies";
import unionBy from "lodash.unionby";
type KeyArgs = FieldPolicy<string>["keyArgs"];
export const cursorPagination = (
keyArgs: KeyArgs = ["afterCursor"],
unionByField = "__ref"
): FieldPolicy => ({
keyArgs,
merge(existing, incoming, { args }) {
const incomingResult = incoming ? incoming.data : [];
console.log("Incoming", incomingResult);
const existingResult = existing ? existing.data : [];
console.log("Existing", existingResult);
const hasNextCursor = Boolean(args?.pagination?.afterCursor);
if (hasNextCursor) {
const resultPagination = unionBy(
existingResult,
incomingResult,
unionByField
);
return {
...incoming,
results: resultPagination,
};
}
return incoming;
},
});
Trying to understand why this is happening, I returned to my request, which is done as follows
export const usePaginationPosts = () => {
const [getPaginatedPosts, { data, fetchMore }] = usepostsLazyQuery({
fetchPolicy: "cache-and-network",
});
const [afterCursor, setAfterCursor] =
(useState < string) | null | (undefined > null);
const [isLoading, setIsLoading] = useState(false);
const getPosts = useCallback(async () => {
setIsLoading(true);
try {
const response = await getPaginatedPosts({
variables: {
input: { limit: 10, afterCursor: null, type: PostFilterType.New },
},
});
setAfterCursor(response.data?.posts.pageInfo?.afterCursor);
console.log(
"response.data?.posts.pageInfo?.afterCursor",
response.data?.posts.pageInfo?.afterCursor
);
} finally {
setIsLoading(false);
}
}, []);
useEffect(() => {
getPosts();
}, [getPosts]);
const getMorePosts = useCallback(async () => {
if (afterCursor) {
const response = await fetchMore({
variables: {
input: { limit: 10, afterCursor, type: PostFilterType.New },
},
});
setAfterCursor(response.data?.posts.pageInfo?.afterCursor);
}
console.log(afterCursor);
}, []);
return { isLoading, getPosts, getMorePosts, data };
};
My theory is that the problem is in afterCursor Just in case, here is my cache option:
export const cacheOption: InMemoryCacheConfig = {
typePolicies: {
Query: {
fields: {
posts: defaultCursorPagination,
userMe: defaultCursorPagination,
},
},
},
};
also query the request:
query posts($input: FindPostsRequest!) {
posts(input: $input) {
data {
author {
firstName
lastName
avatarUrl
}
createdAt
description
id
isLiked
likesCount
mediaUrl
title
}
pageInfo {
afterCursor
count
perPage
}
}
}
I will be grateful for any help
I think you're using
keyArgs"the wrong way round" here.The point of
keyArgsis to say "if this argument is different, the underlying data does not belong together".So the way you use it, each different
afterCursorwill be in a different cache entry and things will never merge together.You would instead put something like
filtersinkeyArgs, to prevent that listings with different filters would not end up in the same cache entry.