Angular reactive form custom validator with parameter
In our previous topic 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.
The following built-in validators have parameters.
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.
Custom Validator with parameter
Code Explanation
Finally do not forget to updated the validation error message in the validationMessages structure
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
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.
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.',
},
};
No comments:
Post a Comment