Angular Custom Validator

One of the characteristics that have always stood out for me in Angular, compared to different frameworks such as React and Vue.js, has been its built-in forms. I favor reactive forms over template-driven forms so this tutorial will be concentrated on implementing validators the reactive way.

Angular Built-in Validators

Angular offers client-side(Browser) form validation. Angular came up with built-in validators like required, minLength, maxLength, and pattern.

But on the other hand, we cannot totally depend on those built-invalidators. Sometimes, with the clients’ requirements, we should be able to create custom rules for form validations. This is where a custom validator comes-in very handy.

class Validators {

  static min(min: number): ValidatorFn

  static max(max: number): ValidatorFn

  static required(control: AbstractControl): ValidationErrors | null

  static requiredTrue(control: AbstractControl): ValidationErrors | null

  static email(control: AbstractControl): ValidationErrors | null

  static minLength(minLength: number): ValidatorFn

  static maxLength(maxLength: number): ValidatorFn

  static pattern(pattern: string | RegExp): ValidatorFn

  static nullValidator(control: AbstractControl): ValidationErrors | null

  static compose(validators: ValidatorFn[]): ValidatorFn | null

  static composeAsync(validators: AsyncValidatorFn[]): AsyncValidatorFn | null

}

Angular Form Validation

Template-driven validation

If your validation is much simpler, then it is more convenient to go with the Template-driven validation structure. To add validation to a template-driven form, you add the same validation attributes as you would with native HTML form validation. Angular uses directives to match these attributes with validator functions in the framework.

Each time the value of a form control changes, Angular runs validation and produces either a list of validation errors, which results in an INVALID status or null, which results in a VALID status.

<input id="name" name="name" class="form-control"
      required minlength="4" appForbiddenName="bob"
      [(ngModel)]="hero.name" #name="ngModel" >

<div *ngIf="name.invalid && (name.dirty || name.touched)"
    class="alert alert-danger">

  <div *ngIf="name.errors.required">
    Name is required.
  </div>
  <div *ngIf="name.errors.minlength">
    Name must be at least 4 characters long.
  </div>
  <div *ngIf="name.errors.forbiddenName">
    Name cannot be Bob.
  </div>

</div>

Reactive form validation

Angular affords us many valuable validators, including required, minLength, maxLength, and pattern. These validators are section of the Validators class, which comes with the @angular/forms package.

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null)
    });
}

To operate with validators, make sure to import them into the component class:

import { FormGroup, FormControl, Validators } from '@angular/forms';

Custom Form Validators

When applying Reactive Forms in Angular, it’s very simple to define custom validators, as they are nothing more than regular functions. You could generate the function for your custom validator inside your component file quickly if the validator won’t be used elsewhere, but here we’ll assume re-use and create a validator in a separate file.

To pass parameters to a custom validator you need to follow these steps:

  1. Construct a factory function and pass parameters that will be passed to the custom validator to this function.
  2. The return type of the factory function should be ValidatorFn which is part of @angular/forms
  3. Return the custom validator from the factory function.
Angular Custom Validator
function ageRangeValidator(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
            return { 'ageRange': true };
        }
        return null;
    };
}

use ageRangeValidator with age control and pass the values for max and min as shown in the code below:

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator(this.min, this.max)])
    });
}

Custom form validation is a little tedious to get used to but affords unlimited assistance for any form of validation you are looking to perform. Always remember to export your custom validators from service so you can reuse the validators wherever in your application.

Angular Documentation

You can see more technology-related facts on our website, Stay with Us.

About the author

Sachin Mamoru

Hi, I'm Sachin an aspiring blogger with an obsession for all things tech. This blog is dedicated to helping people learn about technology.

View all posts

Leave a Reply

Your email address will not be published. Required fields are marked *