From e2f34f1f479c067eefa60f9e210734be4040382b Mon Sep 17 00:00:00 2001 From: schroda <50052685+schroda@users.noreply.github.com> Date: Mon, 2 Oct 2023 16:58:32 +0200 Subject: [PATCH] Use gql for "fetchMore" workaround The "loading" and "networkStatus" state do not get correctly updated when e.g. calling "fetchMore". This seems to happen because an abort signal is passed on every hook call. Due to passing this signal, the passed args to the hook change, and thus, it looks like apollo considers this a completely new hook call. By preventing the signal from being passed, the hook correctly updates these states, but, on the contrary, it is not possible to abort these requests anymore --- src/lib/requests/RequestManager.ts | 51 ++++++++++++++++++++++++------ src/screens/Updates.tsx | 1 + 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/lib/requests/RequestManager.ts b/src/lib/requests/RequestManager.ts index ff73f275..2515b45e 100644 --- a/src/lib/requests/RequestManager.ts +++ b/src/lib/requests/RequestManager.ts @@ -14,11 +14,11 @@ import { ApolloQueryResult, DocumentNode, FetchResult, - MutationHookOptions, - MutationOptions, + MutationHookOptions as ApolloMutationHookOptions, + MutationOptions as ApolloMutationOptions, MutationTuple, - QueryHookOptions, - QueryOptions, + QueryHookOptions as ApolloQueryHookOptions, + QueryOptions as ApolloQueryOptions, QueryResult, TypedDocumentNode, useMutation, @@ -217,10 +217,41 @@ type SWRInfiniteResponseLoadInfo = { isLoadMore: boolean; }; -type ApolloPaginatedMutationOptions = MutationHookOptions< +type CustomApolloOptions = { + /** + * This is a workaround for an apollo bug (?). + * + * A new abort signal gets passed on every hook call. + * This causes the passed arguments to change (due to updating the "context" option, which is only relevant for the actual request), + * which - I assume - results in apollo to handle this as a completely new hook call. + * Due to this, when e.g. calling "fetchMore", "loading" and "networkStatus" do not get updated when enabling "notifyOnNetworkStatusChange". + * + * By not passing an abort signal, the states get correctly updated, BUT it won't be possible to abort the request. + */ + omitAbortSignal?: boolean; +}; +type QueryOptions = ApolloQueryOptions< + Variables, + Data +> & + CustomApolloOptions; +type QueryHookOptions = ApolloQueryHookOptions< Data, Variables -> & { skipRequest?: boolean }; +> & + CustomApolloOptions; +type MutationHookOptions = Partial< + ApolloMutationHookOptions +> & + CustomApolloOptions; +type MutationOptions = Partial< + ApolloMutationOptions +> & + CustomApolloOptions; +type ApolloPaginatedMutationOptions< + Data = any, + Variables extends OperationVariables = OperationVariables, +> = MutationHookOptions & { skipRequest?: boolean }; type AbortableRequest = { abortRequest: AbortController['abort'] }; export type AbortableAxiosResponse = { response: Promise } & AbortableRequest; @@ -730,7 +761,7 @@ export class RequestManager { context: { ...options?.context, fetchOptions: { - signal, + signal: options?.omitAbortSignal ? undefined : signal, ...options?.context?.fetchOptions, }, }, @@ -746,7 +777,7 @@ export class RequestManager { context: { ...options?.context, fetchOptions: { - signal, + signal: options?.omitAbortSignal ? undefined : signal, ...options?.context?.fetchOptions, }, }, @@ -762,7 +793,7 @@ export class RequestManager { context: { ...options?.context, fetchOptions: { - signal, + signal: options?.omitAbortSignal ? undefined : signal, ...options?.context?.fetchOptions, }, }, @@ -778,7 +809,7 @@ export class RequestManager { context: { ...options?.context, fetchOptions: { - signal, + signal: options?.omitAbortSignal ? undefined : signal, ...options?.context?.fetchOptions, }, }, diff --git a/src/screens/Updates.tsx b/src/screens/Updates.tsx index 4766c434..6f0b95b6 100644 --- a/src/screens/Updates.tsx +++ b/src/screens/Updates.tsx @@ -113,6 +113,7 @@ const Updates: React.FC = () => { } = requestManager.useGetRecentlyUpdatedChapters(undefined, { fetchPolicy: 'cache-and-network', notifyOnNetworkStatusChange: true, + omitAbortSignal: true, }); const hasNextPage = !!chapterUpdateData?.chapters.pageInfo.hasNextPage; const endCursor = chapterUpdateData?.chapters.pageInfo.endCursor;