Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: Validators.email invalid if empty

I'm creating an app in Angular (4.0), that contains a form (FormGroup). In this form I have an email input (with FormControl), and I use Validators.email for validation.

import { Validators } from '@angular/forms';

// ...
let validators = [];
if ([condition]) {
    validators.push(Validators.email);
}
let fc = new FormControl([value] || '', validators);
// ...

But when the input is empty, it is invalid (it has an ng-invalid class), even if it's not required.

Is this a proper behavior? What can I do?

like image 621
Roland Rácz Avatar asked May 11 '17 15:05

Roland Rácz


3 Answers

eric2783's solution is pretty good, however - if, in future, the output of Validators.email will change, then this custom validator will become not compatible with the angular's validator output.

Here's what you should do to keep the compatibility:

private customEmailValidator(control: AbstractControl): ValidationErrors {
  if (!control.value) {
    return null;
  }

  return Validators.email(control);
}
like image 69
matewka Avatar answered Oct 16 '22 21:10

matewka


The best solution that i found was this:

<input type="email" name="email" [(ngModel)]="model.Email" [email]="model.Email!='' && model.Email!=null">
like image 23
Alexandre N. Avatar answered Oct 16 '22 22:10

Alexandre N.


You can accomplish what you want with a custom validator. Here's the validator I wrote to get it to work:

private customEmailValidator(control: AbstractControl): {[key: string]: any} {
    const emailError = Validators.email(control);
    if (control.value && emailError) {
        return {'email': {}};
    }

    return null;
}

Then you can replace validators.push(Validators.email); with validators.push(this.customEmailValidator);

It uses angular's built in email validator but also makes sure the email control has a value before returning an error.

like image 28
erics2783 Avatar answered Oct 16 '22 23:10

erics2783