Validating user input is a fundamental part of building web applications. Forms are the primary interface through which users provide data, and it is crucial to ensure that this data is accurate, consistent, and secure. Angular provides a robust validation framework that makes it simple to validate forms using both template-driven and reactive forms approaches.
At the core of Angular’s validation system are built-in validators, which allow developers to enforce common validation rules such as required fields, email format, minimum and maximum length, and patterns. Built-in validators are simple to implement, reusable, and work seamlessly with Angular’s form controls.
In this guide, we will explore Angular’s built-in validators in detail. We will cover their purpose, usage in both template-driven and reactive forms, examples with multiple fields, error handling, and best practices for using validators in production-ready applications.
What Are Validators?
Validators are functions or rules that determine whether a form control’s value meets specific criteria. They are executed whenever the value of a form control changes, ensuring real-time validation feedback. Validators return an error object if the value is invalid, or null if the value is valid.
Angular provides two types of validators:
- Synchronous Validators – execute immediately and return validation results.
- Asynchronous Validators – execute asynchronously, often used for server-side validation (e.g., checking if a username exists).
In this post, we focus on Angular’s built-in synchronous validators, which cover the most common validation scenarios.
Using Validators in Template-Driven Forms
Template-driven forms rely primarily on directives in the HTML template. Built-in validators can be applied using attributes such as required
, minlength
, maxlength
, and email
.
Example: Simple Template-Driven Form
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm)">
<label for="username">Username:</label>
<input id="username" name="username" ngModel required minlength="3" maxlength="15" />
<div *ngIf="userForm.submitted && userForm.controls.username?.errors">
<small *ngIf="userForm.controls.username?.errors?.required">Username is required.</small>
<small *ngIf="userForm.controls.username?.errors?.minlength">Minimum 3 characters required.</small>
<small *ngIf="userForm.controls.username?.errors?.maxlength">Maximum 15 characters allowed.</small>
</div>
<label for="email">Email:</label>
<input id="email" name="email" ngModel required email />
<div *ngIf="userForm.submitted && userForm.controls.email?.errors">
<small *ngIf="userForm.controls.email?.errors?.required">Email is required.</small>
<small *ngIf="userForm.controls.email?.errors?.email">Enter a valid email address.</small>
</div>
<button type="submit">Submit</button>
</form>
Key Points:
required
ensures the field is not empty.minlength
andmaxlength
enforce character length constraints.email
validates the input against a standard email pattern.- Error messages are displayed only when the form is submitted and invalid.
Using Validators in Reactive Forms
Reactive forms provide a more programmatic approach. Validators are applied when creating FormControl
instances in the component’s TypeScript code.
Importing Validators
import { FormGroup, FormControl, Validators } from '@angular/forms';
Example: Reactive Form with Built-in Validators
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-user-form',
templateUrl: './user-form.component.html'
})
export class UserFormComponent implements OnInit {
userForm!: FormGroup;
ngOnInit() {
this.userForm = new FormGroup({
username: new FormControl('', [
Validators.required,
Validators.minLength(3),
Validators.maxLength(15)
]),
email: new FormControl('', [
Validators.required,
Validators.email
])
});
}
onSubmit() {
if (this.userForm.valid) {
console.log('Form submitted:', this.userForm.value);
} else {
console.log('Form is invalid');
}
}
}
Template for Reactive Form
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
<label for="username">Username:</label>
<input id="username" formControlName="username" />
<div *ngIf="userForm.get('username')?.invalid && userForm.get('username')?.touched">
<small *ngIf="userForm.get('username')?.errors?.required">Username is required.</small>
<small *ngIf="userForm.get('username')?.errors?.minlength">Minimum 3 characters required.</small>
<small *ngIf="userForm.get('username')?.errors?.maxlength">Maximum 15 characters allowed.</small>
</div>
<label for="email">Email:</label>
<input id="email" formControlName="email" />
<div *ngIf="userForm.get('email')?.invalid && userForm.get('email')?.touched">
<small *ngIf="userForm.get('email')?.errors?.required">Email is required.</small>
<small *ngIf="userForm.get('email')?.errors?.email">Enter a valid email address.</small>
</div>
<button type="submit" [disabled]="userForm.invalid">Submit</button>
</form>
Detailed Overview of Built-in Validators
1. Validators.required
Ensures that the form control has a value.
- Returns
{ required: true }
if the control is empty. - Works for text inputs, checkboxes, and selects.
Example:
username: new FormControl('', Validators.required)
2. Validators.email
Validates that the input matches a standard email format.
- Returns
{ email: true }
if the value is not a valid email. - Uses a regex pattern internally.
Example:
email: new FormControl('', [Validators.required, Validators.email])
3. Validators.minLength
Ensures that the input meets a minimum character length.
- Returns
{ minlength: { requiredLength: x, actualLength: y } }
if the value is shorter.
Example:
password: new FormControl('', Validators.minLength(6))
4. Validators.maxLength
Ensures that the input does not exceed a maximum character length.
- Returns
{ maxlength: { requiredLength: x, actualLength: y } }
if the value is longer.
Example:
username: new FormControl('', Validators.maxLength(20))
5. Validators.pattern
Validates input against a regex pattern. Useful for custom validation requirements.
Example: Only letters and numbers
username: new FormControl('', Validators.pattern(/^[a-zA-Z0-9]+$/))
Combining Multiple Validators
Multiple validators can be combined using an array in reactive forms:
email: new FormControl('', [
Validators.required,
Validators.email,
Validators.minLength(5),
Validators.maxLength(50)
])
- Validation fails if any validator returns an error.
- Angular aggregates all errors in the
errors
object.
Accessing Validation Errors
To display meaningful messages, access the errors
object:
const usernameErrors = this.userForm.get('username')?.errors;
if (usernameErrors?.required) {
console.log('Username is required');
}
if (usernameErrors?.minlength) {
console.log(Minimum ${usernameErrors.minlength.requiredLength} characters required
);
}
- Use
touched
ordirty
states to show errors only after user interaction.
Real-Time Validation Feedback
Angular forms allow real-time validation, showing errors as users type:
<input id="username" formControlName="username" />
<div *ngIf="userForm.get('username')?.invalid && userForm.get('username')?.dirty">
<small *ngIf="userForm.get('username')?.errors?.required">Username is required.</small>
<small *ngIf="userForm.get('username')?.errors?.minlength">Minimum 3 characters required.</small>
</div>
dirty
checks if the user modified the field.- Provides immediate feedback and improves user experience.
Practical Example: Registration Form
this.registrationForm = new FormGroup({
username: new FormControl('', [Validators.required, Validators.minLength(3), Validators.maxLength(15)]),
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required, Validators.minLength(6)]),
confirmPassword: new FormControl('', Validators.required)
});
- Combine multiple validators for robust validation.
- Use
confirmPassword
with a custom validator to match the password.
Best Practices for Validators
- Use built-in validators first – They cover most common scenarios.
- Combine validators thoughtfully – Avoid redundant rules.
- Provide user-friendly error messages – Explain what went wrong clearly.
- Use reactive forms for complex validation – Dynamic or conditional rules are easier to manage.
- Validate on blur or submit – Prevent overwhelming the user with too many errors at once.
- Create custom validators for unique rules – Extend Angular’s built-in system.
Leave a Reply