Skip to content

Instantly share code, notes, and snippets.

@dralletje
Created June 25, 2025 12:43
Show Gist options
  • Save dralletje/e8f1fc622ae2b4d4965bd4d56abffa04 to your computer and use it in GitHub Desktop.
Save dralletje/e8f1fc622ae2b4d4965bd4d56abffa04 to your computer and use it in GitHub Desktop.
`useFragment` composable for Vue & Apollo
import type { Reference, StoreObject, TypedDocumentNode } from '@apollo/client';
/**
* Returns an always-up-to-date view of whatever data the cache currently contains for a given fragment and useFragment
* never triggers network requests of its own.
*
* Based on https://www.apollographql.com/docs/react/api/react/hooks#usefragment code at https://github.com/apollographql/apollo-client/blob/a8fe0a1217d9784d3165e0ec2e88a2caca0f82d7/src/react/hooks/useFragment.ts#L1-L108
*
* I've taken this from https://github.com/vuejs/apollo/issues/1510 with a bit more tweaks from the apollo react codebase.
*
* @param fragment
* @param from
* @param fragmentName
*/
export function useFragment<TResult = unknown, TVariables = unknown>(
fragment: TypedDocumentNode<TResult, TVariables>,
from: MaybeRefOrGetter<StoreObject | Reference | string | null | undefined>,
fragmentName?: string,
) {
const { client } = useApolloClient();
const data = shallowRef<TResult | undefined>(undefined);
const complete = shallowRef<boolean>(false);
let unsubscribe: (() => void) | undefined = undefined;
watchEffect(() => {
const unwrappedFrom = toValue(from);
// Remove our previous subscription
if (unsubscribe !== undefined) {
unsubscribe();
}
// If we have a from that is not "empty" we good!
if (unwrappedFrom !== undefined && unwrappedFrom !== null) {
unsubscribe = client.cache.watch<TResult, TVariables>({
returnPartialData: true,
immediate: true,
id: typeof unwrappedFrom === 'string' ? unwrappedFrom : client.cache.identify(unwrappedFrom),
// eslint-disable-next-line @typescript-eslint/dot-notation
query: client.cache['getFragmentDoc'](fragment, fragmentName), // This is private, lol!
optimistic: false,
callback(diff) {
// TODO: There is more to this I think: https://github.com/apollographql/apollo-client/blob/a8fe0a1217d9784d3165e0ec2e88a2caca0f82d7/src/react/hooks/useFragment.ts#L77-L82
data.value = diff.result;
complete.value = diff.complete ?? false;
},
});
}
});
return { data: data, complete: complete };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment