Search code examples
formsangularcustom-validators

How to make a custom validator in Angular2


I am making an custom validator for checking if the input is a valid email format.

This is my Validator class:

import {FormControl} from "@angular/forms";

export class EmailValidator {

    static getEmailValidator() {
        return function emailValidator(control: FormControl): { [s: string]: boolean } {

            if (!control.value.match(/^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/)) {
                return {invalidChars: true};
            }
       }
    }
}

My HTML looks like that:

<div class="form-group">

    <input  class="form-control"
            [(ngModel)]="model.email"
            type="text"
            id="name"
            placeholder="Enter your email"
            [formControl]="signupForm.controls['email']"

     >
     <div *ngIf="signupForm.controls['email'].errors?.required&& signupForm.controls['email'].touched"
          class="alert alert-danger">Email is required</div>
     <div *ngIf="signupForm.controls['email'].hasError('invalidChars') && signupForm.controls['email'].touched"
          class="alert alert-danger">Please give a valid email address</div>

My Component to the HTML:

export class SignupComponent  {


    signupForm: FormGroup;
    email: AbstractControl;

    model: any = {};
    response: any;


    constructor(fb: FormBuilder, private userService: UserService) {
        this.signupForm = fb.group({
            'email' : ['', Validators.compose([Validators.required, EmailValidator.getEmailValidator()])]

        });
        this.email = this.signupForm.controls['email'];
    }

And finally the exception I get:

Uncaught (in promise): Error: Error in ./SignupComponent class 
SignupComponent - inline template:31:4 caused by: Cannot read property 
'match' of undefined TypeError: Cannot read property 'match' of undefined at
 emailValidator

My question is why my match is undefined, and how would be the most appropriate to implement a custom validator?


Solution

  • As the validator itself looks fine, the error looks much like your control.value is undefined as it is pristine. Update emailValidator function to the following:

    static getEmailValidator() { 
        return function emailValidator(control: FormControl): { [s: string]: boolean } {
    
            if (control.value && !control.value.match(/^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$/)) {
                return {invalidChars: true};
            }
        }
    

    So it will try to test value with the regex only in case there is one provided one.