Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: clean error message for singular fields after unmount #3385

Merged
merged 2 commits into from Jul 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/vee-validate/src/useForm.ts
Expand Up @@ -292,6 +292,9 @@ export function useForm<TValues extends Record<string, any> = Record<string, any

function registerField(field: PrivateFieldComposite) {
fields.value.push(field);
// TODO: Do this automatically on registration
// eslint-disable-next-line no-unused-expressions
fieldsById.value; // force computation of the fields ids to properly set their idx
if (isRef(field.name)) {
valuesByFid[field.fid] = field.value.value;
// ensures when a field's name was already taken that it preserves its same value
Expand Down Expand Up @@ -338,10 +341,17 @@ export function useForm<TValues extends Record<string, any> = Record<string, any
// cleans up the field value from fid lookup
nextTick(() => {
delete valuesByFid[fid];
// clears a field error on unmounted
// we wait till next tick to make sure if the field is completely removed and doesn't have any siblings like checkboxes
// #3384
if (!fieldsById.value[fieldName]) {
setFieldError(fieldName, undefined);
}
});
const fieldName = unref(field.name);
// in this case, this is a single field not a group (checkbox or radio)
// so remove the field value key immediately

if (field.idx === -1) {
// avoid un-setting the value if the field was switched with another that shares the same name
// they will be unset once the new field takes over the new name, look at `#registerField()`
Expand All @@ -353,6 +363,7 @@ export function useForm<TValues extends Record<string, any> = Record<string, any

unsetPath(formValues, fieldName);
unsetPath(initialValues.value, fieldName);

return;
}

Expand Down
28 changes: 28 additions & 0 deletions packages/vee-validate/tests/Form.spec.ts
Expand Up @@ -2115,4 +2115,32 @@ describe('<Form />', () => {
// field was re-checked
expect(span.textContent).toBe('');
});

test('field errors should be removed when its unmounted', async () => {
const isShown = ref(true);
const wrapper = mountWithHoc({
setup() {
return {
isShown,
};
},
template: `
<VForm v-slot="{ errors }">
<Field v-if="isShown" name="fname" rules="required"/>
<span>{{ errors.fname }}</span>
</VForm>
`,
});

await flushPromises();
const span = wrapper.$el.querySelector('span');
setValue(wrapper.$el.querySelector('input'), '');
await flushPromises();
expect(span.textContent).toBe(REQUIRED_MESSAGE);
isShown.value = false;

await flushPromises();
// field was re-checked
expect(span.textContent).toBe('');
});
});