Support us .Net Basics C# SQL ASP.NET Aarvi MVC Slides C# Programs Subscribe Download

Angular reactive form custom validator with parameter

Suggested Videos
Part 13 - Move validation logic to the component class in reactive form | Text | Slides
Part 14 - Dynamically adding or removing form control validators in reactive form | Text | Slides
Part 15 - Angular reactive form custom validator | Text | Slides

In this video we will discuss creating and using a custom validator with parameters. This is continuation to Part 15. Please watch Part 15 from Angular 6 tutorial before proceeding.


In our previous video we discussed creating a custom email domain validator. The following is that validator function.

function emailDomain(control: AbstractControl): { [key: string]: any } | null {
  const email: string = control.value;
  const domain = email.substring(email.lastIndexOf('@') + 1);
  if (email === '' || domain.toLowerCase() === 'pragimtech.com') {
    return null;
  } else {
    return { 'emailDomain': true };
  }
}


Notice, the domain name 'pragimtech.com' is hard coded. So this custom validator, only works if you want to check if the domain is pragimtech.com. What if you want to check another domain like microsoft.com. We want to make this custom validator reusable with any domain name. We should be able to pass the domain name as a parameter to the emailDomain custom validator function.

Notice in the example below, we are passing pragimtech.com as the domain name. If you want to check for a different domain, you simply pass that domain name as a parameter.

email: ['', [emailDomain('pragimtech.com')]]

The following built-in validators have parameters.
  • min
  • max
  • minlength
  • maxlength
Notice the min() built-in validator function. It takes in a number as a parameter and returns ValidatorFn.

min(min: number): ValidatorFn;

So, what is ValidatorFn?
ValidatorFn stands from validator function. So this min() function is taking in a number as a parameter and returns a validator function. If you understand the concept of closure in JavaScript, then this is very easy to understand. We discussed closures in detail in Parts 27 and 28 of JavaScript tutorial.

In simple terms, you can thinks of a closure as, a function inside another function i.e an inner function and an outer function. The inner function has access to the outer function’s variables and parameters in addition to it's own variables and parameters.

Now that task at hand for us, is to convert our emailDomain() function to take in the domain name as a parameter and return a validator function. To be able to do this we are going to take the advantage of closures in JavaScript.

ValidatorFn is an interface and the signature of the function it returns is as shown below. It takes the AbstractControl that we want to validate as an input parameter and returns null or ValidationErrors object. Null if the validation succeeds and a ValidationErrors object is the validation has failed.

(c: AbstractControl): ValidationErrors | null;

Custom Validator with parameter

function emailDomain(domainName: string) {
  return (control: AbstractControl): { [key: string]: any } | null => {
    const email: string = control.value;
    const domain = email.substring(email.lastIndexOf('@') + 1);
    if (email === '' || domain.toLowerCase() === domainName.toLowerCase()) {
      return null;
    } else {
      return { 'emailDomain': true };
    }
  };
}

Code Explanation
  • We have 2 functions here. An inner function and an outer function.
  • The outer function has a name (emailDomain), but the inner function does not have a name. It is an anonymous function.
  • The inner anonymous function has access to the outer function parameter domainName.
  • You can have as many parameters as you want in the outer function, then inner function will have access to all of them in addition to it's own parameters.
Passing the value for the custom validator parameter

email: ['', [Validators.required, emailDomain('dell.com')]]

Finally do not forget to updated the validation error message in the validationMessages structure

validationMessages = {
  'email': {
    'required': 'Email is required.',
    'emailDomain': 'Email domian should be dell.com'
  },
  'proficiency': {
    'required': 'Proficiency is required.',
  },
};

angular 6 tutorial for beginners

No comments:

Post a Comment

It would be great if you can help share these free resources