adopted-ember-addons / ember-changeset

Ember.js flavored changesets, inspired by Ecto
http://bit.ly/ember-changeset-demo
MIT License
431 stars 141 forks source link

Validations break when calling validate in constructor #574

Closed tehmaestro closed 2 years ago

tehmaestro commented 3 years ago

Version

3.0.0

Test Case

https://ember-twiddle.com/af4b69756b682ca2cc6ee1d97d499ab6?openFiles=components.login-form%5C.js%2Ctemplates.components.login-form%5C.hbs

Steps to reproduce

Hi, I am trying to accomplish two things:

Trying to resolve the first issue, I thought I should manually call validate in the constructor, so that changeset.isValid has the correct value, immediately after the initial rendering of the component. However, calling it directly, and not scheduling it in the runloop, caused the validations to break completely . I mean, I would write in the username field, than I would delete the text, and no validations would occur. This is the only way I managed to get it working.

The second issue is more of a question. Is there a field level isDirty attribute already in existence? Am I missing it in the docs? Is this a valid way of extending the changeset class ?

Thank you so much.

Expected Behavior

Call validate in the constructor and the validations should keep working.

Actual Behavior

After calling validate in the constructor, the validations break, sometimes errors are not populated, probably some validations do not run at all, when changing the input fields.

jbescoyez commented 3 years ago

@tehmaestro Just encountered the same behavior. Did you find a workaround?

snewcomer commented 3 years ago

https://github.com/poteto/ember-changeset/issues/602

What is the error specifically? I'm thinking it was this? We don't necessarily support this atm b/c it leads to read - then - write errors while rendering.

tehmaestro commented 3 years ago

Hi, I cannot remember the error, but I think it is the same case. What I did is schedule the validate function later.

    constructor() {
        super(...arguments);
        this.buildChangeset();
    }

    buildChangeset() {
        this.changeset = new Changeset(...);
        scheduleOnce('actions', () => {
            this.changeset.validate();
        });
    }
snewcomer commented 3 years ago

One looming question in my mind is do you have a need to validate on render? Would love to hear why!

tehmaestro commented 3 years ago

Well I guess the issue is that if you are rendering a button and use disabled={{this.changeset.isInvalid}}, on a login form, the initial value of isInvalid will be false, so the button will be enabled and clickable. When in fact, it should not be clickable, as the username and password fields are in an invalid state, as they are empty.

But I think this depends a lot on your UI, and also, you could use the isDirty attribute too for the initial state of the button, something like disabled={{or this.changeset.isInvalid (not isDirty)}}

I still think that a field level isDirty attribute would be cool. I need to maintain my own logic right now, as I don't want to show all errors for all fields, while the user is typing inside one field.

snewcomer commented 3 years ago

@tehmaestro What version are you on? I believe we fixed that specific issue.

https://github.com/validated-changeset/validated-changeset/pull/133

snewcomer commented 2 years ago

closing for now. Please let me know if we need to reopen!