How to check if a FormControl has a `min` validator

Unfortunately `hasValidator` does not work well with validators created dynamically like `Validator.min` but there is a solution that allows getting information about min value anyway.

You can view the source code for this project by following this link: GitHub

Problem with hasValidator

Let’s create a simple FormControl with min validator. To check if the control has some validator we can use the hasValidator method but it does not work correctly for Validators.min(3) because calling Validators.min(3) creates another reference and the implementation of hasValidator check validators by reference.

import { FormControl, Validators } from "@angular/forms";
const passwordControl = new FormControl(null, [Validators.min(3)]);
passwordControl.hasValidator(Validators.min(3)); // -> false
const minThreeValidator = Validators.min(3);
const confirmPassword = new FormControl(null, [minThreeValidator]);
confirmPassword.hasValidator(minThreeValidator); // -> true

Checking if a control has a min validator without hasValidator

To check if the control has a min validator we can use knowledge about numbers. We can get all control’s validators and check if we get the min error for -Infinity.

import { AbstractControl, FormControl, Validators } from "@angular/forms";
const minAgeControl = new FormControl(null, [Validators.required, Validators.min(18)]);
const hasMinValidator = hasControlMinValidator(minAgeControl);
console.log(hasMinValidator); //-> true
function hasControlMinValidator(control: AbstractControl): boolean {
const validator = control.validator;
if (validator === null) {
return false;
}
const errors = validator(new FormControl(-Infinity)) ?? {};
return "min" in errors;
}

Because nothing can be lesser than -Infinity we are sure that we cause an error if the validator contains min validator.

Getting min value from the validator

To get information about the min value from the validator first we need to cause an error. In the error details, we have information about the min value and actual value of a control.

import { AbstractControl, FormControl, Validators } from "@angular/forms";
const minAgeControl = new FormControl(null, [Validators.required, Validators.min(18)]);
const minValue = getMinValue(minAgeControl);
console.log(minValue); //-> 18
function getMinValue(control: AbstractControl, fallback: number): number;
function getMinValue(control: AbstractControl): number | undefined;
function getMinValue(control: AbstractControl, fallback?: number): number | undefined {
const validator = control.validator;
if (validator === null) {
return fallback;
}
const errors = validator(new FormControl(-Infinity)) ?? {};
return "min" in errors ? errors["min"]["min"] : fallback;
}

We have to write errors['min']['min'] because first min is the error key and the second min is the value passed as the argument of Validators.min function.

const control = new FormControl(2, Validators.min(3));
console.log(control.errors); // {min: {min: 3, actual: 2}}

Do you like the content?

Your support helps me continue my work. Please consider making a donation.

Donations are accepted through PayPal or Stripe. You do not need a account to donate. All major credit cards are accepted.

Portrait of the author

About me

A JavaScript specialist with many years of industry experience whose heart beats for Angular. A follower of the "Keep it simple, stupid" principle and a fan of clean code and good architecture. Fearless in the face of the toughest challenges, I always look for simple and effective solutions. As a pragmatist and an enthusiast of new technologies, I passionately follow the trends in the JavaScript world. After hours — a sailor who loves discovering new places and spending time on trips. My favorite motto? "Talk is cheap. Show me the code."

Leave a comment