Skip to content

Commit

Permalink
fix: run silent validation after array mutations closes #4096
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Mar 2, 2023
1 parent 6e784cc commit 044b4b4
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 7 deletions.
17 changes: 12 additions & 5 deletions packages/vee-validate/src/useFieldArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,12 @@ export function useFieldArray<TValue = unknown>(arrayPath: MaybeRef<string>): Fi
return entry;
}

function afterMutation() {
updateEntryFlags();
// Should trigger a silent validation since a field may not do that #4096
form?.validate({ mode: 'silent' });
}

function remove(idx: number) {
const pathName = unref(arrayPath);
const pathValue = getFromPath<TValue[]>(form?.values, pathName);
Expand All @@ -105,7 +111,7 @@ export function useFieldArray<TValue = unknown>(arrayPath: MaybeRef<string>): Fi
form?.unsetInitialValue(pathName + `[${idx}]`);
form?.setFieldValue(pathName, newValue);
fields.value.splice(idx, 1);
updateEntryFlags();
afterMutation();
}

function push(value: TValue) {
Expand All @@ -121,7 +127,7 @@ export function useFieldArray<TValue = unknown>(arrayPath: MaybeRef<string>): Fi
form?.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);
form?.setFieldValue(pathName, newValue);
fields.value.push(createEntry(value));
updateEntryFlags();
afterMutation();
}

function swap(indexA: number, indexB: number) {
Expand Down Expand Up @@ -162,13 +168,14 @@ export function useFieldArray<TValue = unknown>(arrayPath: MaybeRef<string>): Fi
newFields.splice(idx, 0, createEntry(value));
form?.setFieldValue(pathName, newValue);
fields.value = newFields;
updateEntryFlags();
afterMutation();
}

function replace(arr: TValue[]) {
const pathName = unref(arrayPath);
form?.setFieldValue(pathName, arr);
initFields();
afterMutation();
}

function update(idx: number, value: TValue) {
Expand All @@ -194,7 +201,7 @@ export function useFieldArray<TValue = unknown>(arrayPath: MaybeRef<string>): Fi
form?.stageInitialValue(pathName + `[${newValue.length - 1}]`, value);
form?.setFieldValue(pathName, newValue);
fields.value.unshift(createEntry(value));
updateEntryFlags();
afterMutation();
}

function move(oldIdx: number, newIdx: number) {
Expand All @@ -218,7 +225,7 @@ export function useFieldArray<TValue = unknown>(arrayPath: MaybeRef<string>): Fi

form?.setFieldValue(pathName, newValue);
fields.value = newFields;
updateEntryFlags();
afterMutation();
}

const fieldArrayCtx: FieldArrayContext<TValue> = {
Expand Down
91 changes: 89 additions & 2 deletions packages/vee-validate/tests/useFieldArray.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useForm, useFieldArray, FieldEntry } from '@/vee-validate';
import { onMounted, Ref } from 'vue';
import { useForm, useFieldArray, FieldEntry, FormContext, FieldArrayContext } from '@/vee-validate';
import { nextTick, onMounted, Ref } from 'vue';
import * as yup from 'yup';
import { mountWithHoc, flushPromises } from './helpers';

Expand Down Expand Up @@ -140,3 +140,90 @@ test('duplicate calls yields the same instance', async () => {
expect(document.querySelector('#arr1')?.innerHTML).toBe('two');
expect(document.querySelector('#arr2')?.innerHTML).toBe('two');
});

// #4096
test('array push should trigger a silent validation', async () => {
let form!: FormContext;
let arr!: FieldArrayContext;
mountWithHoc({
setup() {
form = useForm<any>({
initialValues: {
users: ['one'],
},
validationSchema: yup.object({
users: yup.array().of(yup.string().required().min(1)),
}),
});

arr = useFieldArray('users');
},
template: `
<div></div>
`,
});

await flushPromises();
expect(form.meta.value.valid).toBe(true);
arr.push('');
await flushPromises();
expect(form.meta.value.valid).toBe(false);
});

// #4096
test('array prepend should trigger a silent validation', async () => {
let form!: FormContext;
let arr!: FieldArrayContext;
mountWithHoc({
setup() {
form = useForm<any>({
initialValues: {
users: ['one'],
},
validationSchema: yup.object({
users: yup.array().of(yup.string().required().min(1)),
}),
});

arr = useFieldArray('users');
},
template: `
<div></div>
`,
});

await flushPromises();
expect(form.meta.value.valid).toBe(true);
arr.prepend('');
await flushPromises();
expect(form.meta.value.valid).toBe(false);
});

// #4096
test('array insert should trigger a silent validation', async () => {
let form!: FormContext;
let arr!: FieldArrayContext;
mountWithHoc({
setup() {
form = useForm<any>({
initialValues: {
users: ['one', 'two'],
},
validationSchema: yup.object({
users: yup.array().of(yup.string().required().min(1)),
}),
});

arr = useFieldArray('users');
},
template: `
<div></div>
`,
});

await flushPromises();
expect(form.meta.value.valid).toBe(true);
arr.insert(1, '');
await flushPromises();
expect(form.meta.value.valid).toBe(false);
});

0 comments on commit 044b4b4

Please sign in to comment.