Why you should never use form.invalid 🙅‍♂️

Thomas King - Dec 5 '23 - - Dev Community

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
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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!

. . . . . . . . .