ThisCalculator

Everyday

Angular Validation Errors: When to Show Them

Updated · Standard formula, shown below

Angular Validation Errors: When to Show Them

Showing validation errors at the right time in Angular forms is a common UX challenge. This guide explains the standard approaches—on submit, on blur, or on change—and provides step-by-step instructions for implementing them using Angular’s reactive forms and template-driven forms. You’ll learn how to control when errors appear, avoid annoying users with premature messages, and create a smoother form experience.

What You’ll Need

  • An Angular project (version 12 or later recommended)
  • Basic knowledge of Angular forms (either reactive or template-driven)
  • Angular CLI installed if you need to create a new project

Step-by-Step

We’ll cover three common strategies: show errors on submit, on blur, and on change. You can pick one or combine them (e.g., show on blur after first submit attempt).

  1. Set up your form. For reactive forms, import ReactiveFormsModule in your module. Create a FormGroup with controls, e.g., email and password. For template-driven forms, use FormsModule and add ngModel with name attributes.
  2. Add validation rules. In reactive forms, add validators like Validators.required and Validators.email. In template-driven, use directives like required and email.
  3. Strategy 1: Show errors on submit. Create a boolean flag, e.g., submitted = false. In your submit handler, set this.submitted = true before checking validity. In the template, show errors only if submitted is true and the control is invalid. For example: *ngIf="submitted && email.invalid". This is the most common and least intrusive approach.
  4. Strategy 2: Show errors on blur. Use the blur event on the input. In reactive forms, you can use a directive or simply set a flag when the control loses focus. A simpler way is to use the touched state. Angular marks a control as touched after the user blurs it. So show errors when email.touched && email.invalid. This shows errors after the user leaves the field, which is good for inline validation.
  5. Strategy 3: Show errors on change. Use the dirty state. A control is dirty after the user changes its value. Show errors when email.dirty && email.invalid. This can be too aggressive if the user is typing, so combine with blur or a debounce if needed.
  6. Combine strategies for better UX. A common pattern is to show errors on submit, but after the first submit, also show them on blur or change. You can achieve this by setting a flag after the first submit, then using email.touched or email.dirty in addition to the flag.
  7. Display error messages. Use Angular’s *ngIf to conditionally show a small error message. For example: Email is required.. You can also use a helper method to get the first error message.
  8. Style the errors. Add a CSS class like .invalid to the input when errors are shown. Use Angular’s [class.invalid]="email.touched && email.invalid" to style the border red.
  9. Test your implementation. Run your app and try all scenarios: submit with empty fields, blur a field, type in a field, etc. Ensure errors appear only when intended.

Common Mistakes

  • Showing errors on every keystroke. Using dirty alone can be annoying. Always consider using touched or a submit flag.
  • Forgetting to set the submit flag. If you don’t set submitted = true in the submit handler, errors will never show on submit.
  • Using pristine instead of dirty. pristine means the field hasn’t been changed, so it’s not what you want for showing errors after change.
  • Not checking errors object. Use control.errors?.required to avoid null pointer errors.
  • Showing all errors at once. If you have multiple validators, show only the first error or a generic message to avoid overwhelming the user.

Tips

  • Use a custom directive to encapsulate the show-on-blur logic if you have many forms.
  • Consider using Angular Material which has built-in error state handling with mat-error.
  • Accessibility: Use aria-describedby to link the error message to the input for screen readers.
  • Debounce input changes if you want to show errors while typing but not after every character.
  • Keep error messages short and specific. For example, “Email is required” rather than “Field is invalid”.

Troubleshooting

  • Errors never show. Check that you have the correct control reference in the template. For reactive forms, ensure you use form.controls.email or the alias from formControlName. For template-driven, use the ngModel reference with #email="ngModel".
  • Errors show immediately on page load. This usually happens if you use dirty or touched before the user interacts. Use submitted flag to delay.
  • Errors don’t clear after fixing. Angular automatically updates the invalid state when the user corrects the input. If not, check that your validators are correctly attached.
  • Only some errors show. If you have multiple validators, ensure you check each error type separately. Use control.hasError('required') for clarity.
  • Form is invalid but submit doesn’t trigger errors. Make sure your submit button is type="submit" and you have a (ngSubmit) handler on the form.

Frequently Asked Questions

  1. What is the difference between touched and dirty? touched becomes true when the user blurs the control (leaves the field). dirty becomes true when the user changes the value. Both stay true once triggered.
  2. How do I show errors only after the first submit attempt? Set a flag in the submit handler and use that flag in your *ngIf conditions. After the first submit, you can also start showing errors on blur.
  3. Can I use ngModel with reactive forms? No, you should not mix them. Use either reactive or template-driven consistently. For reactive forms, use formControlName.
  4. How do I show a generic error message for a field? Use control.invalid to show a generic message, but it’s better to show specific messages for each validation rule.
  5. What is the best strategy for large forms? For large forms, showing errors on submit is usually best to avoid overwhelming the user. After the first submit, you can switch to on-blur.
  6. How do I reset the validation state? Call form.reset() to clear all states. You can also use control.markAsUntouched() and control.markAsPristine() to reset individual controls.

Related

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.