To display validation errors in Angular, add validators to a form control and show a message when that control is invalid and the user has interacted with it. Check the specific error key—such as required or minlength—so the message explains what needs fixing. Template-driven forms read state from NgModel; reactive forms read it from the corresponding control.
Choose when an error should appear
A required field can be invalid as soon as an empty form loads, but showing an error before someone has tried to use the field can be distracting. A common pattern is to display a message when the control is invalid and either touched or dirty:
As an Amazon Associate I earn from qualifying purchases.
control.invalid && (control.dirty || control.touched)
touched becomes true after the user focuses and leaves a control; dirty indicates that its value has changed. For a simpler pattern, show the message only after the field is no longer pristine. Angular’s template-driven forms guide demonstrates hiding a required-field message while the control is valid or pristine.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteUse text that identifies the problem and, where useful, tells the user how to correct it. Color alone does not explain why a value was rejected.
#1 Best Overall
Display errors in a template-driven form
Template-driven forms commonly apply validators with familiar HTML attributes. Angular matches attributes such as required to validator functions. Export the control as an NgModel template reference variable, then check its state and error keys:
<form #profileForm="ngForm">
<label for="name">Name</label>
<input
id="name"
name="name"
required
minlength="3"
[(ngModel)]="profile.name"
#name="ngModel"
>
<div *ngIf="name.invalid && (name.dirty || name.touched)">
<p *ngIf="name.hasError('required')">Enter your name.</p>
<p *ngIf="name.hasError('minlength')">Use at least 3 characters.</p>
</div>
</form>
The template reference provides access to the control’s validity and interaction state. Testing each error key ensures that the message matches the failed rule instead of displaying a generic warning. Angular’s validation guide also demonstrates this pattern with a custom forbidden-name error.
Rank #2
Display errors in a reactive form
Reactive forms define controls and validators in the component model. The template can then read each control’s errors and state. This example shows a required message and a minimum-length message:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsimport { FormControl, FormGroup, Validators } from '@angular/forms';
profileForm = new FormGroup({
name: new FormControl('', [Validators.required, Validators.minLength(3)]),
});
<form [formGroup]="profileForm">
<label for="name">Name</label>
<input id="name" formControlName="name">
<ng-container *ngIf="profileForm.controls.name as name">
<div *ngIf="name.invalid && (name.dirty || name.touched)">
<p *ngIf="name.hasError('required')">Enter your name.</p>
<p *ngIf="name.hasError('minlength')">Use at least 3 characters.</p>
</div>
</ng-container>
</form>
Angular’s reactive forms guide documents model-defined controls and built-in validators; its validation guide explains how control status and errors can drive displayed messages.
Rank #3
Handle cross-field and asynchronous validation
Cross-field rules
When a rule compares multiple fields, attach its error to the parent form group rather than assigning blame to just one child. Then check the group’s error and interaction state in the template. Angular’s example uses actorForm.hasError('unambiguousRole') and gates the message on the group being touched or dirty. This keeps the validation result associated with the combination of values that caused it.
Asynchronous rules
Async validators return a Promise or Observable. Account for the control’s pending state while the check is running so the interface does not treat an unfinished check as a final result. Angular runs asynchronous validators only after synchronous validators pass. See the official validation guide for the validation lifecycle and examples.
Rank #4
Template-driven or reactive forms?
Both approaches support conditional error messages. The main difference is where the form and its validation rules are defined, which affects how naturally each approach fits the form’s complexity.
| Approach | Where rules live | Custom validation | Typical fit |
|---|---|---|---|
| Template-driven | In the template, using attributes and directives | A directive wraps the validator and registers it through NG_VALIDATORS |
Small or simple forms |
| Reactive | In the component model, on controls | Validator functions are attached to controls | More complex forms where explicit form modeling is useful |
Angular describes these trade-offs in its forms overview and validation guide. Choose the approach that matches the form; either way, display a message by checking the relevant control or group state.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




