Custom Validators in Angular

In Angular, there are few built-in validators, but they are not always matched with your need, so in that case, you’ll have to create a custom validator in angular.

In this blog post, we’ll learn how to create custom validators in angular reactive forms. If you are beginners in reactive forms, I would recommend reading my previous article Getting Started with Angular Reactive Forms

We’ll create a custom validator for product quantity validation.


Custom Validators

Let suppose we want to create validators for quantity to be in the range from 5 to 15. Since angular doesn’t provide range validator we’ll create a custom validator for this specific scenario.

Validators are just a function, that takes input as AbstractControl instance and returns either null if it is valid or an error object if it’s not valid.

Let’s create custom validator called quantityRangeValidator


function quantityRangeValidator(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 { quantityRange: true };
    }
    return null;
  };
}

As you can see in the above function we’ve passed control as a parameter and got the value from it and validated the value from 5 to 15 in the if clause

1) FAIL: If validation fails then it will return an error object.
2) SUCCESS: If validation succeeds, it will return null.

Now we’ll see how can we use this validator inside reactive forms.


constructor(private fb: FormBuilder) {}
  form = this.fb.group({
    name: ["", Validators.required],
    quantity: ["", quantityRangeValidator]
  });

As you can see that we can declare it the same way as we are declaring built-in validators.

We can display the error in the template if the quantity is invalid as following:


<div>
	<h2>Angular Reactive Form Custom Validation</h2>
	<form [formgroup]="form" (ngsubmit)="onSubmit()">
		<div> <label>Name: </label> <input formcontrolname="name" type="text">
			<div class="error" ngif="form.get('name').hasError('required')"> Name is required</div>
		</div>
		<div> <label>Quantity: </label> <input formcontrolname="quantity" type="text">
			<div class="error" ngif="form.get('quantity').errors && form.get('quantity').errors.quantityRange"> Quantity
				Range is invalid</div>
		</div>
		<div> <button type="submit">Submit</button></div>
	</form>
</div>

Passing Parameters to Custom Validator

Now let’s take a look into the more advanced custom validator. we’ll pass the dynamic value of min and max quantity instead of the static value of 5 and 15.   To pass the parameter to a custom validator, we need to create a factory function which will take the parameters to get the min and max value and returns validator function.  


function quantityRangeValidator(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 { quantityRange: true };
    }
    return null;
  };
}

As you can see in the above code, we are passing min and max parameter to validate the value of the quantity.

We can user parameterized custom validators in angular reactive forms as following:


constructor(private fb: FormBuilder) {}
  form = this.fb.group({
    name: ["", Validators.required],
    quantity: ["", quantityRangeValidator(20, 30)]
  });

Here we are passing min value as 20 and max value as 30.

We can display the error in the template if a quantity is invalid as following:


<div>
	<h2>Angular Reactive Form Custom Validation</h2>
	<form [formgroup]="form" (ngsubmit)="onSubmit()">
		<div> <label>Name: </label> <input formcontrolname="name" type="text">
			<div class="error" ngif="form.get('name').hasError('required')"> Name is required</div>
		</div>
		<div> <label>Quantity: </label> <input formcontrolname="quantity" type="text">
			<div class="error" ngif="form.get('quantity').errors && form.get('quantity').errors.quantityRange"> Quantity
				Range is invalid</div>
		</div>
		<div> <button type="submit">Submit</button></div>
	</form>
</div>

And that’s it, that’s all the custom validators are.


Thanks for reading the article.

Also, read:

  If you like this post, please share it with your friends.