logaretm / vee-validate

✅ Painless Vue forms
https://vee-validate.logaretm.com/v4
MIT License
10.74k stars 1.26k forks source link

Form not marked as dirty if new value is empty object #4678

Open hendrikheil opened 6 months ago

hendrikheil commented 6 months ago

What happened?

Currently, if a value is changed to an empty object ({}), the isEqual util automatically assumes nothing has changed.

https://github.com/logaretm/vee-validate/blob/cdf0a803c642e85f159603998a623deb91c25fb2/packages/vee-validate/src/utils/assertions.ts#L164-L165

I think checking both objects and comparing their key counts would be a viable option to solving this without a noticable performance hit.

Reproduction steps

  1. Create any form with initial values:
    const form = useForm({
    initialValues: {
    a: {
      exists: true,
    }
    }
    });
  2. Empty the value of a
    const [a] = form.defineField('a');
    a.value = {};
  3. Inspect form.meta.dirty, this should be true, but it is false

Version

Vue.js 3.x and vee-validate 4.x

What browsers are you seeing the problem on?

Relevant log output

No response

Demo link

https://stackblitz.com/edit/vee-validate-issue-template-p3dgzu?file=src%2FApp.vue,src%2Fmain.ts

Code of Conduct

evpaassen commented 5 months ago

The isssue is not limited to empty objects. Actually, every single attribute combination may be missing without the form being marked as dirty. Take this example: https://stackblitz.com/edit/vee-validate-issue-template-i9yukh?file=src%2FApp.vue

The problem is indeed in the isEqual function in utils/assertions.ts. Since the change in 32537e1 (#4341), this method is not commutative anymore and I think that is a bug. This is demonstrated here: https://stackblitz.com/edit/vee-validate-issue-template-bsm92l?file=src%2FApp.vue

Maybe I can try to come up with a PR to fix it.