Suggested Videos
Part 12 - Move validation messages to the component class in reactive form | Text | Slides
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
In this video we will discuss, creating and using a custom validator in an Angular reactive form.
Angular provides several built-in validator functions like required, pattern, minLength, maxLength, etc. Most of our application validation requirements can be met using one or more of the these built-in validator functions. However, sometimes we may need custom validation logic.
For example,
let's say we only want to allow an email address with pragimtech.com as the domain.
Any other email domain is invalid.
We can achieve this very easily using a custom validator. Here are the steps.
Step 1 : Create the custom validator function
Just like a builtin validator, a custom validator is also a function. If you take a look at the required built-in function, notice it takes AbstractControl as a parameter. Both FormControl and FormGroup inherits from AbstractControl class. Specifying AbstractControl as parameter type, allows us to pass either a FormControl or a FormGroup to validate.
Notice the return type is either ValidationErrors object or null. The method returns null if the control passes validation otherwise ValidationErrors object. If you take a look at the definition of ValidationErrors type, it is an object with a key and a value. Key is a string and value can be anything. But we usually specify a value of true to indicate that there is a validation error.
In the template, we use this same key to display the validation error message.
Step 2 : Attach the custom validator function to the control that we want to validate
Step 3 : Display the validation error message
If you want the validation error message and logic in the template, then check for emailDomin key on the errors collection of email form control
On the other hand, if you want the validation error message and logic in the component class, then include the validation message in validationMessages object as shown below.
Here is the formErrors object which holds the messages to display. The template will bind to this object.
This logValidationErrors() method checks if a control has failed validation. If it has, it populates the formErrors object, with the validation error message using the form control name as the key.
In the template bind to the email property on the formErrors object
Part 12 - Move validation messages to the component class in reactive form | Text | Slides
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
In this video we will discuss, creating and using a custom validator in an Angular reactive form.
Angular provides several built-in validator functions like required, pattern, minLength, maxLength, etc. Most of our application validation requirements can be met using one or more of the these built-in validator functions. However, sometimes we may need custom validation logic.
For example,
let's say we only want to allow an email address with pragimtech.com as the domain.
Any other email domain is invalid.
We can achieve this very easily using a custom validator. Here are the steps.
Step 1 : Create the custom 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 };
}
}
Just like a builtin validator, a custom validator is also a function. If you take a look at the required built-in function, notice it takes AbstractControl as a parameter. Both FormControl and FormGroup inherits from AbstractControl class. Specifying AbstractControl as parameter type, allows us to pass either a FormControl or a FormGroup to validate.
required(control: AbstractControl): ValidationErrors | null;
Notice the return type is either ValidationErrors object or null. The method returns null if the control passes validation otherwise ValidationErrors object. If you take a look at the definition of ValidationErrors type, it is an object with a key and a value. Key is a string and value can be anything. But we usually specify a value of true to indicate that there is a validation error.
{ [key: string]: any }
In the template, we use this same key to display the validation error message.
Step 2 : Attach the custom validator function to the control that we want to validate
email: ['', [Validators.required, emailDomain]]
Step 3 : Display the validation error message
If you want the validation error message and logic in the template, then check for emailDomin key on the errors collection of email form control
<span
*ngIf="employeeForm.get('email').errors.emailDomain">
Email domian should be prgaimtech.com
</span>
On the other hand, if you want the validation error message and logic in the component class, then include the validation message in validationMessages object as shown below.
validationMessages = {
'fullName': {...
},
'email': {
'required': 'Email
is required.',
'emailDomain': 'Email
domian should be pragimtech.com'
},
'phone': {...
},
'skillName': {...
},
'experienceInYears':
{...
},
'proficiency': {...
},
};
Here is the formErrors object which holds the messages to display. The template will bind to this object.
formErrors = {
'fullName': '',
'email': '',
'phone': '',
'skillName': '',
'experienceInYears':
'',
'proficiency': ''
};
This logValidationErrors() method checks if a control has failed validation. If it has, it populates the formErrors object, with the validation error message using the form control name as the key.
logValidationErrors(group: FormGroup = this.employeeForm):
void {
Object.keys(group.controls).forEach((key: string) =>
{
const abstractControl = group.get(key);
if (abstractControl instanceof
FormGroup) {
this.logValidationErrors(abstractControl);
} else {
this.formErrors[key] = '';
if (abstractControl && !abstractControl.valid
&& (abstractControl.touched || abstractControl.dirty)) {
const messages = this.validationMessages[key];
for (const errorKey in
abstractControl.errors) {
if
(errorKey) {
this.formErrors[key]
+= messages[errorKey] + ' ';
}
}
}
}
});
}
In the template bind to the email property on the formErrors object
<div
class="form-group"
[ngClass]="{'has-error':
formErrors.email}">
<label class="col-sm-2
control-label" for="email">Email</label>
<div class="col-sm-8">
<input id="email"
type="text"
class="form-control"
formControlName="email"
(blur)="logValidationErrors()">
<span class="help-block"
*ngIf="formErrors.email">
{{formErrors.email}}
</span>
</div>
</div>
You miss this step in ur video so output will not as like you sir
ReplyDeletespan *ngIf="employeeForm.get('email').errors.emailDomain">
Email domian should be prgaimtech.com
span>