wearebraid / vue-formulate

⚡️ The easiest way to build forms with Vue.
https://vueformulate.com
MIT License
2.25k stars 245 forks source link

Validation shows old errors until promises from custom rules are resolved #176

Open devmaslov opened 4 years ago

devmaslov commented 4 years ago

Describe the bug Suppose there's an input with the following validation rules: required|^email|available_email where available_email is a custom rule which checks if email is available for registration (sends request to API) and returns a Promise that resolves boolean. While typing invalid email, validation fails and shows a corresponding error. But when "email" rule passed and validation starts checking the last one (which returns a Promise) the old message is still displayed until the promise of the last rule is resolved. It looks like this:

download

You can see that the input itself already contains a valid email, but it still shows the last error until the Promise from the last rule is resolved. In my opinion if a rule passed the validation check, the corresponding errors should be hidden right away, without waiting for the rest of the rules to be resolved.

To Reproduce

  1. Create an input with a set of validation rules where one of them returns is a Promise that resolves in a couple seconds.
  2. Set error-behavior="live"
  3. Enter some values and you'll see that the error list is updated only once the last Promise is resolved, not after they passed the validation. Which might lead to a confusion, since the old errors are displayed while user made a valid input based on some rules.

Check the CodePen fork for the example.

CodePen:

https://codepen.io/devmaslov/pen/LYGBERJ

Once you open it you can see two errors. Type in an email or just copy past this myemail@gmail.com and you'll see that the errors are still displayed for 5 seconds - until Promise from the last rule is resolved.

Expected behavior The validation state should be updated or errors for passed rules should be removed as fast as possible, without waiting for all Promises to be resolved. Once one of the rule's promise is resolved, then show it's error right away, not waiting for the others. Maybe it makes sense to add a new status like isValidating - which is set to true from the validation start, until all rules are validated and resolved. It could be used to show a user that validation is in progress - might be helpful in some cases.

justin-schroeder commented 4 years ago

Ahh, now this is a nice juicy one haha :) Yeah I agree it's not as good as it could/should be. Currently messages are updated after all rules have run, it’s actually somewhat core to how the validation system works, but this makes a compelling case to change some of that. We still need a long-running promise that resolves after all validation rules have been run so we don't break the hasValidationErrors(): Promise code, but we could decouple the display of errors from that.

I'll noodle on this, if you come up with a good solution feel free to submit a PR too.