Async validator question
Hi,
Is there a way to check if a changeset has changed since it was last validated?
Ideally setting any prop: changeset.set('prop', 1) will turn changeset.get('isValid') false, until all validators (async here is the issue) resolve.
This would allow us to disable UI until we know for certain that everything is resolved and valid.
Currently, if there is a slow async validator, the changeset will be in isValid true, but in reality, it is still unresolved, and therefor, the user may proceed to submit and then the world falls apart.
Let me know what you think.
Thanks
Hey, good question. Ideally it should be invalid during an async validation. I'll have to think about how to implement it in a nice way, but yeah I agree
Excellent. Thank you
Can you give d633440b0aafbeb0a1c484ca53b87aa60b244ad9 a whirl @brancusi? Let me know if that fixes the issue for you - isValid / isInvalid should now take into account any async validation running
Thanks @poteto I have been trying it out.
Just want to add a scenario and see what your thoughts are.
Basically, I would like to run a uniqueness validation. This will hit a unique_check endpoint.
I see now that when I changeset.set("prop", val) it does indeed change the isValid to false until resolved, but here are a few concerns.
- Debouncing the input. I currently debounce outside of the validator which leads us to the next issue
- How can we set the
changesettopendingso that it'sisValid == falsewhile we debounce? Since we debounce outside the validator, we don'tchangeset.set...until the debounce completes, for this reason, the changeset is never directly touched during the debounce delay, and the user could trigger a submit before validation. (I really need a twiddle on this I know)
Lastly, I notice that when we changeset.set("prop", val) and there is an async validator on prop, if we continue to set new values before the validator resolves, anything after gets overwritten when the validator resolves. So you get a broken typing experience.
That is if of course if you bind the value of the input field to {{one-way-input changeset.prop}}. Not sure if that is a bad idea, but even if we don't bind, we still have potential issues with out of order async validations clobbering data.
If we could achieve something like: changeset.clearValidations() to put it back into pending. That could happen as the user starts typing, then debounce and once resolved it would all refire. I would like to avoid tracking state outside of the changeset for things like disabling a submit button.
Hmm, thanks for letting me know. It'll definitely be easier to visualize if you could make a simple twiddle
So check it out with a 1 sec delay: https://ember-twiddle.com/99807edeadef70a3de0973ab6b1a99f8?fileTreeShown=false&openFiles=validators.uniqueness.js%2C
Thanks
Hi @poteto, any ideas on this? Please let me know if you want a different scenario in a twiddle.
Thank you
:+1:
Just my two cents because my needs are (almost) exactly the same. This is a really common scenario :
Given a form with an email input which needs a uniqueness validation check,
- The user writes some characters in the email input
- After some inactivity on this input (maybe 1s), the uniqueness email validation is triggered.
Then, either:
- The user has written some new characters => the uniqueness validation is now outdated and should be ignored
- Or the user did not change this input (but it could have changed another one!) => the uniqueness validation is still up-to-date and should display an error if the email already exists
To recap, ember-changeset needs the following features to resolve this scenario (some of them are probably already implemented) :
- Delay before triggering the validations (probably related to #110)
- Asynchronous validations : the uniqueness validation is done through a server check
- Per-property validations : the user can change another input without triggering again the email validation
- Per-property validation state : the
emailasync validation should be ignored when the user changes the email input value while the validation is still pending
Do ember-changeset/ember-changeset-validation aim to solve this problem ?
I have the same use-case for validating serial numbers. I've looked at the skipValidate. It can work but because it applies to the entire changeset and not just a single property, it makes ugly code to trigger validation on that one property only after debouncing but keep validation on all other properties as they're modified.
Does anybody have a workaround for this issue? Because right now async validations on uniqueness seem te be useless because of the strange way the input field is working with an async validator attached to it..
this worked for me https://gist.github.com/alexdiliberto/b3cf1bee63d93980aec56b7aeb0369f6