Custom Validator In Reactive Forms In Angular

Custom Validator In Reactive Forms In Angular

In this article, you'll learn how to create a custom validator in Angular Reactive form. A significant number of fields can be found on a data entry form. The Angular forms module makes creating, managing, and validating form fields more easier. In Angular, you can design forms in two different methods. The first are reactive forms, while the second are template-driven forms. Learn how to make reactive forms as well as template-driven forms.

Built-in Validators

Validating the forms is critical; otherwise, we would end up with inaccurate data in our database. To assist us in validating the form, the Angular Forms Module includes a few built-in validators. The following is a list of them.

  • Required validator
  • Min length Validator
  • Max length Validator
  • Pattern Validator
  • Email Validator

Custom Validator in Angular Reactive Form

Built-in validators are helpful, but they don't cover every scenario. This is when the custom validator comes in handy. In Angular, creating a custom validator is a breeze.

How to Build Custom Validator

It's just as simple to create a custom Validator as it is to create a Validator function. It's a function that must conform to the ValidatorFn Interface.

ValidatorFn

The ValidatorFn is an Interface that defines the Validator function's signature.

interface ValidatorFn {
  (control: AbstractControl): ValidationErrors | null
}

The AbstractControl is sent to the function. FormControl, FormGroup, and FormArray are all derived from this basic class. If the validation was successful, the validator function must return a list of errors, i.e. ValidationErrors, or null if the validation was unsuccessful.

Custom Validator Example

Create an angular application from scratch. In app.component.html, add the following code.
<h1>Custom Validator in Angular</h1>
 
<h2>Reactive Form</h2>
 
<form formgroup="" myform="" ngsubmit="" novalidate="" onsubmit="">
 
  <div>
    <label>Number :</label>
    <input formcontrolname="numVal" id="numVal" name="numVal" type="text" />
  </div>
 
  <p>Is Form Valid : {{myForm.valid}} </p>
 
  <p>
    <button disabled="" myform.valid="" type="submit">Submit</button>
  </p>
 
</form>

The numVal form field is present in our example app. We'd like it to be higher than ten.

There is no built-in validator for this in Angular. As a result, let us create a custom Validator gte.

Make a new file in the app folder called gte.validator.ts.
import { AbstractControl, ValidationErrors } from '@angular/forms'
 
export function gte(control: AbstractControl): ValidationErrors | null {
 
    const v=+control.value;
 
    if (isNaN(v)) {
      return { 'gte': true, 'requiredValue': 10 }
    }      
 
    if (v <= 10) {
      return { 'gte': true, 'requiredValue': 10 }
    } 
 
    return null
 
}

To begin, import the AbstractControl and ValidationErrors classes from the @angular/forms package.
import { AbstractControl, ValidationErrors } from '@angular/forms'

The ValidatorFn Interface must be followed by the validator function. The AbstractControl should be passed to it as a parameter. FormControl, FormGroup, or FormArray are all possibilities.

If any errors are identified, the function must return ValidationErrors; otherwise, it must return null.
export function gte(control: AbstractControl): ValidationErrors | null {

ValidationErrors is a [key: string]: any key-value pair object that defines the broken rule. The string is the key, and it should include the name of the breached rule. The value can be anything, but it is usually true.

The validation logic is straightforward. Use the isNaN method to see if the control's value is a number. Check to see if the number is less than or equal to ten. If both conditions are true, then null is returned.
const v=+control.value;

if (isNaN(v)) {
  return { 'gte': true, 'requiredValue': 10 }
}      

if (v <= 10) {
  return { 'gte': true, 'requiredValue': 10 }
} 

return null

If the validation fails, the ValidationErrors are returned. You can use anything for the key, although it is recommended that you use the validator's name, i.e. gte. Also, set the value to true. You can also specify a string value.
return { 'gte': true, 'requiredValue': 10 }

As illustrated in the example above, you can return several key-value pairs. The value 10 is returned by the second key requiredValue. This is what we use in the template to display the error message.

Using the Custom Validator

Before you can use this validator, you must first import it into the component class.
import { gte } from './gte.validator';

As illustrated below, add the validator to the FormControl's Validator collection.
myForm = new FormGroup({
  numVal: new FormControl('', [gte]),
})

Below is the entire app.component.ts file.
import { Component } from '@angular/core';
import { FormGroup, FormControl, AbstractControl, ValidationErrors } from '@angular/forms'
import { gte } from './gte.validator';
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
 
  constructor() {
  }
 
  myForm = new FormGroup({
    numVal: new FormControl('', [gte]),
  })
 
  get numVal() {
    return this.myForm.get('numVal');
  }
 
  onSubmit() {
    console.log(this.myForm.value);
  }
}

Accessing the Errors from Custom Validator

We need to give the user a meaningful error message.

Validators produce ValidationErrors as a result of their work. They are included in the control's collection of errors. The control's valid property is set to false.

As a result, we check to see if the property is genuine. We also inspect the property that has been soiled or touched. Because we do not want the error notice to appear when the form is first displayed.
<div>
  <label>Number :</label>
  <input formcontrolname="numVal" id="numVal" name="numVal" type="text" />
  <div ngif="!numVal.valid && (numVal.dirty ||numVal.touched)">
    <div ngif="numVal.errors.gte">
      The number should be greater than {{numVal.errors.requiredValue}}
    </div>
  </div>

</div>

The error message is displayed if the gte is true. It's worth noting that gte is the name of the key we used to build the validator.

The requiredValue is also used to provide a meaningful message to the user.
<div ngif="numVal.errors.gte">
   The number should be greater than {{numVal.errors.requiredValue}}
</div>

We've now completed the development of a custom validator for reactive forms.

Conclusion

Validators are merely functions that implement the ValidatorFn Interface. They are given a Form Control instance. It verifies the authenticity of the control value. ValidationErrors must be returned if validation errors are present. If the validation was successful, return null.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in comment section.

Post a Comment

Previous Post Next Post