In Angular, form validation ensures that user input meets defined requirements before being processed. Angular provides two main approaches for building and validating forms:
🔹 1. Types of Forms in Angular
Template-driven forms
- Simpler, suitable for small forms.
- Validation is declared directly in the template using directives.
- Uses
FormsModule
.
Reactive forms
- More scalable and testable, suited for complex forms.
- Validation rules are defined in the component class.
- Uses
ReactiveFormsModule
.
🔹 2. Template-Driven Form Validation
Example:
<!-- app.component.html -->
<form #myForm="ngForm" (ngSubmit)="onSubmit(myForm)">
<label>Email:</label>
<input type="email" name="email" ngModel required email #emailCtrl="ngModel" />
<div *ngIf="emailCtrl.invalid && emailCtrl.touched">
<small *ngIf="emailCtrl.errors?.['required']">Email is required.</small>
<small *ngIf="emailCtrl.errors?.['email']">Invalid email format.</small>
</div>
<button type="submit" [disabled]="myForm.invalid">Submit</button>
</form>
Enable FormsModule
in app.module.ts
:
import { FormsModule } from '@angular/forms';
@NgModule({
imports: [FormsModule],
})
export class AppModule {}
🔹 3. Reactive Form Validation
Example:
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
})
export class AppComponent {
constructor(private fb: FormBuilder) {}
myForm = this.fb.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(6)]],
});
onSubmit() {
if (this.myForm.valid) {
console.log(this.myForm.value);
}
}
}
<!-- app.component.html -->
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<label>Email:</label>
<input type="email" formControlName="email" />
<div *ngIf="myForm.get('email')?.invalid && myForm.get('email')?.touched">
<small *ngIf="myForm.get('email')?.errors?.['required']">Email is required.</small>
<small *ngIf="myForm.get('email')?.errors?.['email']">Invalid email format.</small>
</div>
<label>Password:</label>
<input type="password" formControlName="password" />
<div *ngIf="myForm.get('password')?.invalid && myForm.get('password')?.touched">
<small *ngIf="myForm.get('password')?.errors?.['required']">Password is required.</small>
<small *ngIf="myForm.get('password')?.errors?.['minlength']">Password must be at least 6 characters.</small>
</div>
<button type="submit" [disabled]="myForm.invalid">Submit</button>
</form>
Enable ReactiveFormsModule
in app.module.ts
:
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
imports: [ReactiveFormsModule],
})
export class AppModule {}
🔹 4. Custom Validators
You can also create your own validator:
import { AbstractControl, ValidationErrors } from '@angular/forms';
export function noSpecialChars(control: AbstractControl): ValidationErrors | null {
const forbidden = /[^a-zA-Z0-9]/.test(control.value);
return forbidden ? { noSpecialChars: true } : null;
}
Usage:
this.myForm = this.fb.group({
username: ['', [Validators.required, noSpecialChars]],
});
✅ In short:
- Use template-driven forms for simple forms.
- Use reactive forms for complex, scalable validation.
- Angular supports built-in validators (
required
,email
,minLength
, etc.) and custom validators.