Skip to content

Commit d779980

Browse files
bgoscinskiBartosz Gościński
authored andcommitted
fix: make sure removePathState removes proper pathState (#4649)
closes #4643 Co-authored-by: Bartosz Gościński <[email protected]>
1 parent 998ca37 commit d779980

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

.changeset/clean-seas-speak.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"vee-validate": patch
3+
---
4+
5+
fix: make sure removePathState removes the correct path state

packages/vee-validate/src/useForm.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,9 @@ export function useForm<
559559
handleSubmit.withControlled = makeSubmissionFactory(true);
560560

561561
function removePathState<TPath extends Path<TValues>>(path: TPath, id: number) {
562-
const idx = pathStates.value.findIndex(s => s.path === path);
562+
const idx = pathStates.value.findIndex(s => {
563+
return s.path === path && (Array.isArray(s.id) ? s.id.includes(id) : s.id === id);
564+
});
563565
const pathState = pathStates.value[idx];
564566
if (idx === -1 || !pathState) {
565567
return;

packages/vee-validate/tests/Form.spec.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { defineRule, useField, Form, Field, useIsValidating } from '@/vee-validate';
1+
import { defineRule, useField, Form, Field, useIsValidating, useForm } from '@/vee-validate';
22
import { mountWithHoc, setValue, setChecked, dispatchEvent, flushPromises } from './helpers';
33
import * as yup from 'yup';
44
import { computed, defineComponent, onErrorCaptured, ref, Ref } from 'vue';
5-
import { InvalidSubmissionContext } from '../src/types';
5+
import { InvalidSubmissionContext, PrivateFormContext } from '../src/types';
66

77
describe('<Form />', () => {
88
const REQUIRED_MESSAGE = `This field is required`;
@@ -3141,3 +3141,40 @@ test('radio fields with single field component binding', async () => {
31413141
expect(model.value).toBe('Tea');
31423142
expect(submit).toHaveBeenLastCalledWith({ drink: 'Tea' }, expect.anything());
31433143
});
3144+
3145+
// #4643
3146+
test('removes proper pathState when field is unmounting', async () => {
3147+
const renderTemplateField = ref(false);
3148+
let form!: PrivateFormContext;
3149+
3150+
mountWithHoc({
3151+
template: `
3152+
<form>
3153+
<Field v-if="renderTemplateField" name="foo" rules="required" />
3154+
</form>
3155+
`,
3156+
setup() {
3157+
form = useForm() as unknown as PrivateFormContext;
3158+
useField('foo');
3159+
return { renderTemplateField };
3160+
},
3161+
});
3162+
3163+
expect(form.meta.value.valid).toBe(true);
3164+
expect(form.getAllPathStates()).toMatchObject([{ id: 0, path: 'foo' }]);
3165+
3166+
renderTemplateField.value = true;
3167+
await flushPromises();
3168+
3169+
expect(form.meta.value.valid).toBe(false);
3170+
expect(form.getAllPathStates()).toMatchObject([
3171+
{ id: 0, path: 'foo' },
3172+
{ id: 1, path: 'foo' },
3173+
]);
3174+
3175+
renderTemplateField.value = false;
3176+
await flushPromises();
3177+
3178+
expect(form.meta.value.valid).toBe(true);
3179+
expect(form.getAllPathStates()).toMatchObject([{ id: 0, path: 'foo' }]);
3180+
});

0 commit comments

Comments
 (0)