Skip to content

Commit 6997d21

Browse files
DutchBenRuben van Leeuwen
andauthored
2226 caching bug (#193)
* 2226: Fixes form caching bug orccuring in some situations where the same for is loading * 2226: Adds changeset --------- Co-authored-by: Ruben van Leeuwen <ruben.vanleeuwen@surf.nl>
1 parent 77beab5 commit 6997d21

File tree

5 files changed

+41
-22
lines changed

5 files changed

+41
-22
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'pydantic-forms': patch
3+
---
4+
5+
Fixes form caching bug

frontend/packages/pydantic-forms/src/core/PydanticFormHandler.tsx

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import React, { useCallback, useEffect, useRef, useState } from 'react';
22
import type { FieldValues } from 'react-hook-form';
33

4+
import _ from 'lodash';
5+
46
import { PydanticFormValidationErrorContext } from '@/PydanticForm';
57
import { useGetConfig, usePydanticForm } from '@/core/hooks';
6-
import { PydanticFormHandlerProps } from '@/types';
8+
import { PydanticFormHandlerProps, PydanticFormSuccessResponse } from '@/types';
79
import { getHashForArray } from '@/utils';
810

911
import { ReactHookForm } from './ReactHookForm';
@@ -19,6 +21,7 @@ export const PydanticFormHandler = ({
1921
const formStepsRef = useRef<FieldValues[]>([]);
2022
const [initialValues, setInitialValues] = useState<FieldValues>();
2123
const [currentFormKey, setCurrentFormKey] = useState<string>(formKey);
24+
const [cacheKey, setCacheKey] = useState<string>(_.uniqueId(formKey));
2225
const formInputHistoryRef = useRef<Map<string, FieldValues>>(
2326
new Map<string, object>(),
2427
);
@@ -47,6 +50,16 @@ export const PydanticFormHandler = ({
4750
}
4851
}, []);
4952

53+
const handleSuccess = (
54+
fieldValues: FieldValues[],
55+
response: PydanticFormSuccessResponse,
56+
) => {
57+
if (onSuccess) {
58+
onSuccess(fieldValues, response);
59+
}
60+
setCacheKey(_.uniqueId(currentFormKey));
61+
};
62+
5063
const {
5164
validationErrorsDetails,
5265
apiError,
@@ -55,7 +68,14 @@ export const PydanticFormHandler = ({
5568
isLoading,
5669
pydanticFormSchema,
5770
defaultValues,
58-
} = usePydanticForm(formKey, config, formStepsRef, onSuccess, formStep);
71+
} = usePydanticForm(
72+
formKey,
73+
config,
74+
formStepsRef,
75+
cacheKey,
76+
handleSuccess,
77+
formStep,
78+
);
5979

6080
const handleStepSubmit = useCallback(
6181
(fieldValues: FieldValues) => {
@@ -74,10 +94,11 @@ export const PydanticFormHandler = ({
7494
}, [restoreHistory]);
7595

7696
const handleCancel = useCallback(() => {
97+
setCacheKey(_.uniqueId(currentFormKey));
7798
if (onCancel) {
7899
onCancel();
79100
}
80-
}, [onCancel]);
101+
}, [currentFormKey, onCancel]);
81102

82103
return (
83104
<PydanticFormValidationErrorContext.Provider

frontend/packages/pydantic-forms/src/core/hooks/useApiProvider.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ export function useApiProvider(
2626
formKey: string,
2727
formInputData: FieldValues[], // TODO: This doesn't seem right
2828
apiProvider: PydanticFormApiProvider,
29+
cacheKey: string,
2930
) {
3031
return useSWR<PydanticFormApiResponse>(
31-
[formKey, formInputData],
32+
[formKey, formInputData, cacheKey],
3233
([formKey, formInputData]) => {
3334
const requestBody = formInputData;
3435

@@ -70,7 +71,6 @@ export function useApiProvider(
7071
throw new Error(error);
7172
});
7273
},
73-
// swr config
7474
{
7575
fallback: {},
7676
revalidateIfStale: true,

frontend/packages/pydantic-forms/src/core/hooks/useLabelProvider.tsx

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
*
1313
* Disabled revalidate / refresh system of SWR, this would cause submissions
1414
*/
15-
import useSWR, { SWRConfiguration } from 'swr';
15+
import useSWR from 'swr';
1616

1717
import {
1818
PydanticFormLabelProvider,
@@ -22,36 +22,28 @@ import {
2222
export function useLabelProvider(
2323
labelProvider?: PydanticFormLabelProvider,
2424
formKey?: string,
25-
id?: string | null,
26-
cacheKey?: number,
27-
swrConfig?: SWRConfiguration,
25+
cacheKey?: string,
2826
) {
2927
return useSWR<PydanticFormLabelProviderResponse | undefined>(
3028
// cache key
31-
[labelProvider, formKey, id, swrConfig, cacheKey],
29+
[labelProvider, formKey, cacheKey],
3230

3331
// return val
3432
async () => {
3533
if (labelProvider) {
3634
return labelProvider({
3735
formKey: formKey || '',
38-
id,
36+
id: cacheKey,
3937
});
4038
}
4139
},
42-
43-
// swr config
4440
{
4541
fallback: {},
46-
47-
// we dont want to refresh the form structure automatically
4842
revalidateIfStale: false,
4943
revalidateOnReconnect: false,
5044
revalidateOnFocus: false,
5145
keepPreviousData: true,
5246
shouldRetryOnError: false,
53-
54-
...swrConfig,
5547
},
5648
);
5749
}

frontend/packages/pydantic-forms/src/core/hooks/usePydanticForm.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ export function usePydanticForm(
3131
formKey: string,
3232
config: PydanticFormConfig,
3333
formStepsRef: React.MutableRefObject<FieldValues[]>,
34-
onSuccess?: (
34+
cacheKey: string,
35+
handleSuccess?: (
3536
fieldValues: FieldValues[],
3637
response: PydanticFormSuccessResponse,
3738
) => void,
@@ -56,7 +57,7 @@ export function usePydanticForm(
5657

5758
// fetch the labels of the form, can also contain default values
5859
const { data: formLabels, isLoading: isLoadingFormLabels } =
59-
useLabelProvider(labelProvider, formKey);
60+
useLabelProvider(labelProvider, formKey, cacheKey);
6061

6162
const formSteps = formStepsRef.current;
6263

@@ -69,7 +70,7 @@ export function usePydanticForm(
6970
data: apiResponse,
7071
isLoading: isLoadingSchema,
7172
error: apiError,
72-
} = useApiProvider(formKey, formInputData, apiProvider);
73+
} = useApiProvider(formKey, formInputData, apiProvider, cacheKey);
7374

7475
// extract the JSON schema to a more usable custom schema
7576
const { pydanticFormSchema, isLoading: isParsingSchema } =
@@ -105,8 +106,8 @@ export function usePydanticForm(
105106
);
106107
return;
107108
} else if (apiResponse.type === PydanticFormApiResponseType.SUCCESS) {
108-
if (onSuccess) {
109-
onSuccess(formInputData, apiResponse);
109+
if (handleSuccess) {
110+
handleSuccess(formInputData, apiResponse);
110111
}
111112
setValidationErrorsDetails(null);
112113
setIsFullFilled(true);

0 commit comments

Comments
 (0)