When doing form validation in Angular, it's best practice to check the form's validity before posting it to the server or processing it. The form itself has a valid
property but also an invalid
property to check for validity. This might lead to this kind of code:
if (form.invalid) {
// show errors
} else {
// process form and continue
}
This will actually work in most cases, but it is deceiving as it might give false positives. And that's the case when using any async validation on the form.
Adding async validation to a form
So you have that same form, but now there's a change incoming that requires you to add some async validation to a form control: check whether the username is already taken.
The user starts typing, fills in an existing username, and immediately hits enter to submit the form. Hopefully the back-end gives you an error message to tell the user this username already exists because the front-end won't do it.
Why is that? Because next to valid
and invalid
, there is a third state called pending
.
As soon as the async validation is triggered on that form control, the form properties valid
and invalid
will be false, but the pending
property will be true. When the async validation has ended, the pending
property will be false, and depending on the result of the async validation, the correct states are set on valid
and invalid
. But by using the existing logic, it will go to the else
condition, process the form, and continue.
To be on the safe side, never use the invalid
property but negate the valid
property:
if (!form.valid) {
// show errors
} else {
// process form and continue
}
Even when using async validation, this will correctly interpret the form validation, i.e., the form is invalid as long as the async validation is not done.
I've created a form status emulator (embedded StackBlitz below) to check for the different statuses a form goes through when editing a form control. Use this playground to check the status of the form according to the update mode and attached validators. In this playground, you can:
- change the update mode to change, blur, or submit.
- add a required validator.
- add a maxlength validator (the maximum length is fixed at 10 characters).
- add an async validator (does an async validation for 4 seconds and checks whether the input starts with "server").
- reset the form
TLDR;
When the form is going through async validation, both valid
and invalid
will be false, whereas the pending
property will be true. This gives false positives because the async validation is not over and could potentially return validation error(s). Use the valid
property to check for correct form validity.
If you have any questions, feel free to contact me!