Skip to content

Commit 8b9a3c8

Browse files
author
Ole Martin Handeland
committed
Tests bumped into a case where queries/mutations are en-route, but because network takes time the navigation hadn't happened quite yet. Waiting for these to finish before showing this message to the user fixes things.
1 parent 58aa6bc commit 8b9a3c8

File tree

2 files changed

+50
-17
lines changed

2 files changed

+50
-17
lines changed

src/components/wrappers/ProcessWrapper.tsx

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Confirm } from 'src/features/processEnd/confirm/containers/Confirm';
2121
import { Feedback } from 'src/features/processEnd/feedback/Feedback';
2222
import { useNavigationParam } from 'src/hooks/navigation';
2323
import { TaskKeys, useIsValidTaskId, useNavigateToTask, useStartUrl } from 'src/hooks/useNavigatePage';
24+
import { useWaitForQueries } from 'src/hooks/useWaitForQueries';
2425
import { getComponentDef, implementsSubRouting } from 'src/layout';
2526
import { RedirectBackToMainForm } from 'src/layout/Subform/SubformWrapper';
2627
import { ProcessTaskType } from 'src/types';
@@ -197,33 +198,34 @@ function useIsWrongTask(taskId: string | undefined) {
197198
const isNavigating = useIsNavigating();
198199
const { data: process } = useProcessQuery();
199200
const currentTaskId = process?.currentTask?.elementId;
201+
const waitForQueries = useWaitForQueries();
200202

201203
const [isWrongTask, setIsWrongTask] = useState<boolean | null>(null);
202204
const isCurrentTask =
203205
currentTaskId === undefined && taskId === TaskKeys.CustomReceipt ? true : currentTaskId === taskId;
204206

205-
const timeoutRef = React.useRef<ReturnType<typeof setTimeout> | null>(null);
206-
207-
// We intentionally delay this state from being set until after a useEffect(), so the navigation error does not
208-
// show up while we're navigating. Without this, the message will flash over the screen shortly in-between all the
209-
// <Loader /> components.
207+
// We intentionally delay this state from being set until after queries/mutations finish, so the navigation error
208+
// does not show up while we're navigating. Without this, the message will flash over the screen shortly
209+
// in-between all the <Loader /> components.
210210
useEffect(() => {
211-
if (timeoutRef.current) {
212-
clearTimeout(timeoutRef.current);
213-
timeoutRef.current = null;
214-
}
215211
if (isCurrentTask) {
216212
setIsWrongTask(false);
217213
} else {
218-
timeoutRef.current = setTimeout(() => {
219-
setIsWrongTask(true);
220-
timeoutRef.current = null;
221-
}, 100);
214+
let cancelled = false;
215+
const delayedCheck = async () => {
216+
await waitForQueries();
217+
await new Promise((resolve) => setTimeout(resolve, 100)); // Wait a bit longer, for navigation to maybe occur
218+
if (!cancelled) {
219+
setIsWrongTask(true);
220+
}
221+
};
222+
delayedCheck().then();
223+
224+
return () => {
225+
cancelled = true;
226+
};
222227
}
223-
224-
const timeout = timeoutRef.current;
225-
return () => void (timeout && clearTimeout(timeout));
226-
}, [isCurrentTask]);
228+
}, [isCurrentTask, waitForQueries]);
227229

228230
return isWrongTask && !isCurrentTask && !isNavigating;
229231
}

src/hooks/useWaitForQueries.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { useCallback } from 'react';
2+
3+
import { useQueryClient } from '@tanstack/react-query';
4+
import type { MutationFilters, QueryFilters } from '@tanstack/react-query';
5+
6+
interface WaitForQueriesOptions {
7+
queryFilters?: QueryFilters;
8+
mutationFilters?: MutationFilters;
9+
}
10+
11+
export function useWaitForQueries(options?: WaitForQueriesOptions) {
12+
const queryClient = useQueryClient();
13+
return useCallback(
14+
async (): Promise<void> =>
15+
new Promise((resolve) => {
16+
const checkQueries = () => {
17+
const isFetching = queryClient.isFetching(options?.queryFilters) > 0;
18+
const isMutating = queryClient.isMutating(options?.mutationFilters) > 0;
19+
20+
if (!isFetching && !isMutating) {
21+
resolve();
22+
} else {
23+
setTimeout(checkQueries, 10);
24+
}
25+
};
26+
27+
checkQueries();
28+
}),
29+
[queryClient, options?.queryFilters, options?.mutationFilters],
30+
);
31+
}

0 commit comments

Comments
 (0)