Skip to content

Instantly share code, notes, and snippets.

@seandearnaley
Last active February 22, 2020 02:03
Show Gist options
  • Save seandearnaley/e1567f1b41b38f68e32bfc178d1f70b8 to your computer and use it in GitHub Desktop.
Save seandearnaley/e1567f1b41b38f68e32bfc178d1f70b8 to your computer and use it in GitHub Desktop.
useRemoveCard.ts beta 37
import {
ApolloError,
FetchResult,
Reference,
ApolloCache,
} from '@apollo/client';
import {
useRemoveCardMutation,
RemoveCardMutation,
Card,
PageInfo,
CardEdge,
} from '../../generated/graphql';
import { buildPageInfo, Edge } from './__utils';
// have to add _ref to the Card Edge type
type CardEdgeWithReference = CardEdge & { node: { __ref: string } };
const removeCardFromCache = (
cache: ApolloCache<RemoveCardMutation>,
categoryId: string,
cardId: string,
) => {
cache.modify(`Category:${categoryId}`, {
cards(cards: Reference, { readField }) {
const edges = readField<CardEdgeWithReference[]>('edges', cards).filter(
edge => edge.node.__ref !== `Card:${cardId}`,
);
let { totalCount } = readField<PageInfo>('pageInfo', cards);
const pageInfo = buildPageInfo<Edge<Card>>(edges, --totalCount, 'Card'); // rebuild pageinfo
return {
edges,
pageInfo,
};
},
});
};
// NOTE: the rationale for using a custom hook is for the cache update,
// now the removeCard function can be used elsewhere with shared cache logic
export const useRemoveCard = (): [
(
id: string,
) => Promise<
FetchResult<RemoveCardMutation, Record<string, any>, Record<string, any>>
>,
boolean,
ApolloError | undefined,
] => {
// note useRemoveCardMutation is generated by GraphQL Code Generator, it is a wrapped useQuery hook
const [removeCardMutation, { loading, error }] = useRemoveCardMutation();
const removeCard = (id: string) =>
removeCardMutation({
variables: {
id,
},
update: (cache, { data }) => {
if (!data) return;
// these cards can be in many categories, data should include a list of category ids
// for each of cards categories, remove the cards from the category cache and recalculate pageInfo
data.removeCard.card.categories.forEach(category =>
removeCardFromCache(cache, category.id, id),
);
// evict this item from the in memory cache
cache.evict(`Card:${id}`);
},
});
return [removeCard, loading, error];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment