Skip to content

Commit

Permalink
fix: make initial values partial closes #4195
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Mar 21, 2023
1 parent 48deea9 commit eeccd0c
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/vee-validate/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface FormMeta<TValues extends Record<string, any>> {
valid: boolean;
validated: boolean;
pending: boolean;
initialValues?: TValues;
initialValues?: Partial<TValues>;
}

export interface FieldState<TValue = unknown> {
Expand Down
11 changes: 5 additions & 6 deletions packages/vee-validate/src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import {
FieldState,
GenericFormValues,
TypedSchema,
YupSchema,
} from './types';
import {
getFromPath,
Expand Down Expand Up @@ -69,7 +68,7 @@ export interface FormOptions<
| TypedSchema<TValues, TOutput>
> {
validationSchema?: MaybeRef<TSchema extends TypedSchema ? TypedSchema<TValues, TOutput> : any>;
initialValues?: MaybeRef<TValues>;
initialValues?: MaybeRef<Partial<TValues>>;
initialErrors?: Record<keyof TValues, string | undefined>;
initialTouched?: Record<keyof TValues, boolean>;
validateOnMount?: boolean;
Expand Down Expand Up @@ -865,7 +864,7 @@ export function useForm<
function useFormMeta<TValues extends Record<string, unknown>>(
fieldsByPath: Ref<FieldPathLookup<TValues>>,
currentValues: TValues,
initialValues: MaybeRef<TValues>,
initialValues: MaybeRef<Partial<TValues>>,
errors: Ref<FormErrors<TValues>>
) {
const MERGE_STRATEGIES: Record<keyof Pick<FieldMeta<unknown>, 'touched' | 'pending' | 'valid'>, 'every' | 'some'> = {
Expand Down Expand Up @@ -899,7 +898,7 @@ function useFormMeta<TValues extends Record<string, unknown>>(

return computed(() => {
return {
initialValues: unref(initialValues) as TValues,
initialValues: unref(initialValues) as Partial<TValues>,
...flags,
valid: flags.valid && !keysOf(errors.value as any).length,
dirty: isDirty.value,
Expand All @@ -918,13 +917,13 @@ function useFormInitialValues<TValues extends GenericFormValues>(
const values = resolveInitialValues(opts);
const providedValues = opts?.initialValues;
// these are the mutable initial values as the fields are mounted/unmounted
const initialValues = ref<TValues>(values);
const initialValues = ref<Partial<TValues>>(values);
// these are the original initial value as provided by the user initially, they don't keep track of conditional fields
// this is important because some conditional fields will overwrite the initial values for other fields who had the same name
// like array fields, any push/insert operation will overwrite the initial values because they "create new fields"
// so these are the values that the reset function should use
// these only change when the user explicitly changes the initial values or when the user resets them with new values.
const originalInitialValues = ref<TValues>(deepCopy(values));
const originalInitialValues = ref<Partial<TValues>>(deepCopy(values)) as Ref<Partial<TValues>>;

function setInitialValues(values: Partial<TValues>, updateFields = false) {
initialValues.value = deepCopy(values);
Expand Down
8 changes: 4 additions & 4 deletions packages/vee-validate/tests/useForm.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,19 +682,19 @@ describe('useForm()', () => {
});

await flushPromises();
expect(formMeta.value.initialValues?.field.name).toBe('1');
expect(formMeta.value.initialValues?.field?.name).toBe('1');
model.value.name = 'test';
await flushPromises();
expect(model.value).toEqual({ name: 'test' });
expect(formMeta.value.initialValues?.field.name).toBe('1');
expect(formMeta.value.initialValues?.field?.name).toBe('1');
reset();
await flushPromises();
expect(model.value).toEqual({ name: '1' });
expect(formMeta.value.initialValues?.field.name).toBe('1');
expect(formMeta.value.initialValues?.field?.name).toBe('1');

model.value.name = 'test';
await flushPromises();
expect(model.value).toEqual({ name: 'test' });
expect(formMeta.value.initialValues?.field.name).toBe('1');
expect(formMeta.value.initialValues?.field?.name).toBe('1');
});
});

0 comments on commit eeccd0c

Please sign in to comment.