Angular - Confirm Password Validation Using Custom Validators
Last Updated :
08 Jan, 2025
Improve
To confirm password validation in Angular forms, you can use a custom validator to ensure two password fields (like password and confirmPassword) match. This is especially useful in sign-up or password reset forms where password confirmation is necessary.
Prerequisite
Steps To Implement CustomConfirm Password Validation
Step 1: Install Angular CLI if you haven't installed it already.
npm install -g @angular/cli
Step 2: Create a new Angular application using the following command.
ng new password-validator-app
Folder Structure

Dependencies
"dependencies": {
"@angular/animations": "^18.2.0",
"@angular/common": "^18.2.0",
"@angular/compiler": "^18.2.0",
"@angular/core": "^18.2.0",
"@angular/forms": "^18.2.0",
"@angular/platform-browser": "^18.2.0",
"@angular/platform-browser-dynamic": "^18.2.0",
"@angular/router": "^18.2.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.10"
}
Step 3: Create the Component Logic
In app.component.ts, create the form using the FormBuilder service, adding custom validators for password complexity requirements and a validator to confirm that the password and confirm password fields match.
//app.component.ts
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import {
FormBuilder,
FormGroup,
ReactiveFormsModule,
Validators,
AbstractControl,
} from '@angular/forms';
import { RouterOutlet } from '@angular/router';
@Component({
selector: 'app-root',
standalone: true,
imports: [RouterOutlet, CommonModule, ReactiveFormsModule],
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'password-validator-app';
passwordForm: FormGroup;
constructor(private fb: FormBuilder) {
this.passwordForm = this.fb.group(
{
password: [
'',
[
Validators.required,
Validators.minLength(6),
this.hasUppercase,
this.hasNumber,
this.hasSpecialCharacter,
],
],
confirmPassword: ['', Validators.required],
},
{ validator: this.passwordMatchValidator }
);
}
// Custom validator to check if passwords match
passwordMatchValidator(form: FormGroup) {
const password = form.get('password')?.value;
const confirmPassword = form.get('confirmPassword')?.value;
if (password !== confirmPassword) {
return { passwordMismatch: true };
}
return null;
}
// Custom validator to check if the password contains at least one uppercase letter
hasUppercase(control: AbstractControl) {
const value = control.value;
if (value && !/[A-Z]/.test(value)) {
return { uppercase: true };
}
return null;
}
// Custom validator to check if the password contains at least one number
hasNumber(control: AbstractControl) {
const value = control.value;
if (value && !/\d/.test(value)) {
return { number: true };
}
return null;
}
// Custom validator to check if the password contains at least one special character
hasSpecialCharacter(control: AbstractControl) {
const value = control.value;
if (value && !/[!@#$%^&*(),.?":{}|<>]/.test(value)) {
return { specialCharacter: true };
}
return null;
}
// Form Submit
onSubmit() {
if (this.passwordForm.valid) {
alert(`Form Submitted Successfully`);
} else {
alert('Please check the form for errors');
}
}
// check if a specific control has a specific error and if it was touched
hasError(controlName: string, errorName: string) {
return (
this.passwordForm.get(controlName)?.hasError(errorName) &&
this.passwordForm.get(controlName)?.touched
);
}
}
In this code
- Password Match Validator (passwordMatchValidator): Verifies that password and confirmPassword fields match.
- Uppercase Validator (hasUppercase): Ensures that the password has at least one uppercase letter.
- Number Validator (hasNumber): Ensures that the password contains at least one number.
- Special Character Validator (hasSpecialCharacter): Ensures that the password includes at least one special character.
Step 4: Create the HTMl template.
In app.component.html, set up the form with the appropriate form controls and error messages
<!-- app.component.html -->
<h1>Password Confirmation Form</h1>
<form [formGroup]="passwordForm" (ngSubmit)="onSubmit()">
<div>
<label for="password">Password:</label>
<input type="password" id="password" formControlName="password" />
</div>
<!-- Error messages for password field -->
<div *ngIf="hasError('password', 'required')">
<p style="color: red">Password is required</p>
</div>
<div *ngIf="hasError('password', 'minlength')">
<p style="color: red">Password must be at least 6 characters long</p>
</div>
<div *ngIf="hasError('password', 'uppercase')">
<p style="color: red">
Password must contain at least one uppercase letter
</p>
</div>
<div *ngIf="hasError('password', 'number')">
<p style="color: red">Password must contain at least one number</p>
</div>
<div *ngIf="hasError('password', 'specialCharacter')">
<p style="color: red">
Password must contain at least one special character
</p>
</div>
<div>
<label for="confirmPassword">Confirm Password:</label>
<input type="password" id="confirmPassword" formControlName="confirmPassword" />
</div>
<!-- Error messages for confirm password field -->
<div *ngIf="passwordForm.errors?.['passwordMismatch'] && passwordForm.get('confirmPassword')?.touched">
<p style="color: red">Passwords do not match!</p>
</div>
<button type="submit" [disabled]="passwordForm.invalid">Submit</button>
</form>
Step 5: Style the Form.
In app.component.css, apply basic styling to improve the form's appearance.
/* app.component.css */
h1 {
text-align: center;
}
form {
max-width: 400px;
margin: 0 auto;
}
div {
margin-bottom: 10px;
}
input {
padding: 5px;
width: 100%;
box-sizing: border-box;
}
button {
padding: 5px 10px;
}
p {
color: red;
font-size: 12px;
}
To run the application, use the below command
ng serve