Create Custom Validators in Angular 16 with Reactive Forms

Last Updated on by in Angular
In this tutorial, you will learn how to create custom validators with Angular and Reactive Forms. You will develop the functionality that tells your users if they’ve entered the correct information in the form field.In simple terms, we’ll create the custom form validations in Angular. Our approach we’ll be like same as we do form validation in Vanilla JavaScript.

Angular offers built-in Validators for form validation. Those powerful validators are maxLength, minLength, required and pattern.

In some complex cases, we need to use custom validation in our form. This is the case where custom validator comes-in handy.

In order to remove strict type warnings or errors make sure to set “strict”: false and "strictTemplates": false under compilerOptions and angularCompilerOptions properties in tsconfig.json file.

Understand Custom Validator in Angular

Let’s say you want the user age should not be more then 18 years. Angular does not offer this kind of validation: hence we will create the custom validator to validate the user’s age.

Creating a custom validator is pretty simple in Angular. It takes one argument, and that is AbstractControl.

The custom validator function will return one of the following:

  • If the validation gets failed, then It’ll return an object having a key-value pair. Where key represents the name of the error and its value will always be (boolean == true).
  • It’ll return null If validation is not failed.

Let us create the custom-validators folder and age.validator.ts file inside the folder. Thereafter, insert the following code within the file.

import { AbstractControl } from '@angular/forms';

export function AgeValidator(
  control: AbstractControl
): { [key: string]: boolean } | null {
  if (control.value > 18) {
    return { age: true };
  }
  return null;
}

Using the Custom Validator in Angular template

Custom Validator is very simple to use, and you have to import in the Angular template. Then pass the custom validator into the form control array argument.

app.component.ts

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import { AgeValidator } from './custom-validators/age.validator';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  constructor(public fb: FormBuilder) {}

  /*##################### Registration Form #####################*/
  validatorForm = this.fb.group({
    name: ['', [Validators.required, AgeValidator]],
  });

  // Getter method to access form control
  get name() {
    return this.validatorForm.get('name');
  }

  // Submit Registration Form
  onSubmit() {
    if (!this.validatorForm.valid) {
      alert('Please enter your age!');
      return false;
    } else {
      alert(JSON.stringify(this.validatorForm.valid));
      // alert(this.validatorForm.value)
    }
  }
}

As you can see, we can also use custom and built-in Validators.required validators together.

How to Access Custom Validators in Angular?

To access the name form control we are using JavaScript getter method.

// Getter method to access form control
get name() {
  return this.validatorForm.get('name');
}

Use your Custom Validators return key, to show the error message in your Angular template.

<div class="invalid-feedback" *ngIf="name.errors?.age">
  <sup>*</sup>Age should not be more than 18 years
</div>

Make sure to add the given code within the app.component.html file.

<div class="jumbotron text-center">
	<h2 class="display-5">
		Angular Custom Validators Example
	</h2>
</div>

<div class="container">
	<div class="row custom-wrapper">
		<div class="col-md-12">
 
			<!-- Form starts -->
			<form [formGroup]="validatorForm" (ngSubmit)="onSubmit()">
				<!-- Full name -->
				<div class="mb-3">
					<label>Tell us your age?</label>
              <input type="text" class="form-control" formControlName="name">

              <!-- error block -->
              <div class="invalid-feedback" *ngIf="name.errors?.['age']">
                <sup>*</sup>Age should not be more than 18 years
              </div>
            </div>

          <!-- Submit Button -->
          <button type="submit" class="btn btn-danger btn-lg btn-block">Submit</button>
      </form><!-- Form ends -->

    </div>
  </div>
</div>

Test Application

Below is the demo in which we are validation the users age, if the age is more then 18 years users will get an error regarding their age.