Introduction
In this article, we will learn about validations in the reactive form in Angular. We will create a simple user registration form and implement some inbuilt validations on it. Along with the inbuilt validations, we will also implement some custom validations to the reactive form. We will consider the following custom validations for this demo.
- Check for user name availability
- Password pattern validation
- Match the password entered in two different fields
Take a look at the application in action.

Prerequisites
Source Code
Get the source code from GitHub.
Create the Angular app
Navigate to the folder where you want to create your project file. Open a command window and run the command shown below.
ng new angular-forms-validation --routing=false --style=scss
We are specifying the command to create a new Angular application. The option to make the routing module is set to false and style files extension is set to scss. This command will create the Angular project with the name angular-forms-validation.
Change the directory to the new project and open the project in VS Code using the set of commands shown below.
- cd angular-forms-validation
- code.
Install Bootstrap
Run the following command to install the Bootstrap library.
npm install bootstrap --save
Add the following import definition in styles.scss file.
@import "~bootstrap/dist/css/bootstrap.css";
Create the validation service
Run the following command to create a new service.
ng g s services\customvalidation
This command will create a folder named services having two files inside it – customvalidation.service.ts and customvalidation.service.spec.ts. Open the customvalidation.service.ts file and put the following code inside it.
import { Injectable } from '@angular/core';
import { ValidatorFn, AbstractControl } from '@angular/forms';
import { FormGroup } from '@angular/forms';
@Injectable({
providedIn: 'root'
})
export class CustomvalidationService {
patternValidator(): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
if (!control.value) {
return null;
}
const regex = new RegExp('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9]).{8,}$');
const valid = regex.test(control.value);
return valid ? null : { invalidPassword: true };
};
}
MatchPassword(password: string, confirmPassword: string) {
return (formGroup: FormGroup) => {
const passwordControl = formGroup.controls[password];
const confirmPasswordControl = formGroup.controls[confirmPassword];
if (!passwordControl || !confirmPasswordControl) {
return null;
}
if (confirmPasswordControl.errors && !confirmPasswordControl.errors.passwordMismatch) {
return null;
}
if (passwordControl.value !== confirmPasswordControl.value) {
confirmPasswordControl.setErrors({ passwordMismatch: true });
} else {
confirmPasswordControl.setErrors(null);
}
}
}
userNameValidator(userControl: AbstractControl) {
return new Promise(resolve => {
setTimeout(() => {
if (this.validateUserName(userControl.value)) {
resolve({ userNameNotAvailable: true });
} else {
resolve(null);
}
}, 1000);
});
}
validateUserName(userName: string) {
const UserList = ['ankit', 'admin', 'user', 'superuser'];
return (UserList.indexOf(userName) > -1);
}
}
The method patternValidator is used to validate the password pattern in our form. The parameter for this method is of type AbstractControl, a base class for the FormControl. We will use a regular expression to validate the password. We will validate the following four conditions using the regular expression.
- The password should be a minimum of eight characters long.
- It has at least one lowercase letter.
- It has at least one upper-case letter.
- It has at least one number.
If the password fails the regex check, we will set the invalid password property to true.
The method MatchPassword is used to compare the passwords in two fields. This method will accept two parameters of type string. These parameters represent the names of the fields to be matched. We will get the FormControl for these two fields and then match their values. If the values do not match, we will set the password mismatch property to true.
The method userNameValidator is used to verify if the username is already taken or not. This method will accept a parameter of type AbstractControl. We will check if the value of this field is present in a static array, UserList. If the value entered by the user is already present, we will set the userNameNotAvailable property to true. We are using the setTimeout function to invoke this check every two seconds. This will ensure that the error will be thrown after two seconds from the time the user stops typing in the field.
Note. For the sake of simplicity of this article, we are using a static array to search for the availability of user names. Ideally, it should be a service call to the server to search for the value in a database.
Create the reactive form component
Run the following command to create the reactive-form component.
ng g c reactive-form
Open reactive-form.component.ts and put the following code in it.
import { Component, OnInit } from '@angular/core';
import { Validators, FormGroup, FormBuilder } from '@angular/forms';
import { CustomvalidationService } from '../services/customvalidation.service';
@Component({
selector: 'app-reactive-form',
templateUrl: './reactive-form.component.html',
styleUrls: ['./reactive-form.component.scss']
})
export class ReactiveFormComponent implements OnInit {
registerForm: FormGroup;
submitted = false;
constructor(
private fb: FormBuilder,
private customValidator: CustomvalidationService
) { }
ngOnInit() {
this.registerForm = this.fb.group({
name: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
username: ['', [Validators.required], this.customValidator.userNameValidator.bind(this.customValidator)],
password: ['', Validators.compose([Validators.required, this.customValidator.patternValidator()])],
confirmPassword: ['', [Validators.required]],
},
{
validator: this.customValidator.MatchPassword('password', 'confirmPassword'),
});
}
get registerFormControl() {
return this.registerForm.controls;
}
onSubmit() {
this.submitted = true;
if (this.registerForm.valid) {
alert('Form Submitted successfully!!!\n Check the values in browser console.');
console.table(this.registerForm.value);
}
}
}
Saba HussainPosted Sep 20, 2021, 9:47 AM
Not all code paths return a value.