Custom Validator In Angular

Introduction

We all know that in every application, validation is a must-have phenomenon. An application without validation is like a security door without its supporting walls.

Custom Validator In Angular

Angular provides some built-in validators but they are not always matched with your requirement. In that case, we have to create a custom validator.

In this article, we’ll learn how to create a custom validator in Reactive Forms.

Prerequisites

  • Reactive Forms in Angular

It’s very easy to define custom validators while working with Reactive Forms. Now, the question is - what exactly is a custom validator. 🤔

What are Custom Validators?

Custom Validators are nothing more than regular functions.

Let’s start creating Custom Validator

  • Create a custom file named as ‘ValidateString.validator.ts’.
  • Import ‘AbstractControl’ into that file.
  • Let’s start creating our validator function.

Let's assume that you have a login page. In that, you want to validate an email. So, we will write a custom validator for this.

  1. import { AbstractControl } from '@angular/forms';  
  2.   
  3. export function ValidateEmail(control:AbstractControl):{[key:string]:Boolean}|null{  
  4.       
  5. let regularExp = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;  
  6.   
  7.     if(control.value!==undefined && !regularExp.test(control.value)){  
  8.       return {"isValidEmail":true};  
  9.     }  
  10.     return null;  
  11. }  

Validator function takes one input parameter of type AbstractControl which is part of Angular Forms. It is a base class of FormControl, FormArray, and FormGroup, and it allows you to read the value of the control passed to the custom validator function.

In the above validator, if our validation fails, it returns an object with key for the error name and a value of true. If the validation passes, it simply returns null.

Use Custom Validator

Let’s start using our email validator. First, import custom validator into our TypeScript file. Use it as shown in the below code.

  1. import { Component, OnInit} from '@angular/core';  
  2. import { FormGroup, FormBuilder, Validators } from '@angular/forms';  
  3. import { ValidateEmail } from './customValidator/email.validator';  
  4.   
  5. @Component({  
  6.   selector: 'app-root',  
  7.   templateUrl: './app.component.html',  
  8.   styleUrls: ['./app.component.css']  
  9. })  
  10. export class AppComponent implements OnInit {  
  11.   LoginForm:FormGroup;  
  12.     
  13.   constructor(private fb:FormBuilder){}  
  14.   
  15.   ngOnInit() {  
  16.     this.LoginForm = this.fb.group({  
  17.       email: ['', [Validators.required, Validators.maxLength(50),  
  18.                    ValidateEmail]],  
  19.       password: ['', [Validators.required,Validators.minLength(8)]],  
  20.       rememberme:[false]  
  21.     });  
  22.   }  
  23. }  

As you see, you have to add the name of the custom validator function in the array; same as in any of the built-in validators. Here, I also add some built-in validators, i.e., required, maxlength, minlength.

  1. <span class='red' *ngIf="LoginForm.get('email').errors  
  2.                          &&(LoginForm.get('email').touched   
  3.                          || LoginForm.get('email').dirty)">  
  4.       <span *ngIf="LoginForm.get('email').errors.required">  
  5.             Email is Required.  
  6.       </span>  
  7.       <span *ngIf="LoginForm.get('email').errors.maxlength">  
  8.              Email must be less than or equal to 50 characters long.  
  9.        </span>  
  10.        <span *ngIf="LoginForm.get('email').errors.isValidEmail">  
  11.              Invalid Email.  
  12.        </span>  
  13. </span>  

In the above template, use custom validator same as another validator.

The entire template will look like the below shared snap.

  1. <div class="container">  
  2.     <h2>Reactive form Validation</h2>  
  3.     <form autocomplete="off" [formGroup]='LoginForm' (ngSubmit)='Login()'>  
  4.         <div class="form-group">  
  5.             <label for="email">Email:</label>  
  6.             <input type="email" formControlName='email' class="form-control" placeholder="Enter email">  
  7.             <span class='red' *ngIf="LoginForm.get('email').errors  
  8.                                     &&(LoginForm.get('email').touched   
  9.                                     || LoginForm.get('email').dirty)">  
  10.                 <span *ngIf="LoginForm.get('email').errors.required">  
  11.                     Email is Required.  
  12.                 </span>  
  13.                 <span *ngIf="LoginForm.get('email').errors.maxlength">  
  14.                     Email must be less than or equal to 50 characters long.  
  15.                 </span>  
  16.                 <span *ngIf="LoginForm.get('email').errors.isValidEmail">  
  17.                     Invalid Email.  
  18.                 </span>  
  19.             </span>  
  20.         </div>  
  21.         <div class="form-group">  
  22.             <label for="password">Password:</label>  
  23.             <input type="password" formControlName='password' class="form-control"  
  24.                    placeholder="Enter password">  
  25.             <span class='red' *ngIf="LoginForm.get('password').errors  
  26.                                      &&(LoginForm.get('password').touched   
  27.                                      || LoginForm.get('password').dirty)">  
  28.                 <span *ngIf="LoginForm.get('password').errors.required">  
  29.                     Password is Required.  
  30.                 </span>  
  31.                 <span *ngIf="LoginForm.get('password').errors.minlength">  
  32.                     Password must be greater than or equal to 8 characters long.  
  33.                 </span>  
  34.             </span>  
  35.         </div>  
  36.         <div class="checkbox">  
  37.             <label><input type="checkbox" formControlName='rememberme'> Remember me</label>  
  38.         </div>  
  39.         <button type="submit" class="btn btn-default">Submit</button>  
  40.     </form>  
  41. </div>  

It’s time to run the application.

Note: Before running the application, make sure that you import ReactiveFormsModule into your module file. Otherwise, you end up with the below error.

Custom Validator In Angular
 
So, let’s initiate a Reactive Form.

Import the ReactiveForms Module into your app.module.ts file which is part of Angular Forms.

Finally, run your application.

If I enter the wrong pattern of email, it will give me an error, i.e., Invalid Email.

Custom Validator In Angular 

That’s it. That's all the custom validators are.

Conclusion

So today, we learned how to create custom validation in Reactive Forms. Thanks a lot for reading. Hopefully, it was helpful to you. Please share with me your suggestions and feedback.