Angular2: email already exist as custom Validator?

∥☆過路亽.° 提交于 2019-12-11 06:55:39

问题


I created a form with Angular2 and I created the following method to check if the email address already exist. Here is my code:

checkEmail(): void {
    // FIRST PART
    this.found = false;
    // If user is not Premium...
    if (!this.currentUser.isPremium) {
        //  ...and if user typed something in the input field, then apply validitor for email address
        if (this.myForm.controls.email.value.length > 0) {
            this.myForm.controls.email.setValidators([validateEmail()]);
            this.myForm.controls.email.updateValueAndValidity();
        // If user leaves the input field blank or empty the typed input, then apply validator for required
        } else {
            this.myForm.controls.email.setValidators([Validators.required]);
            this.myForm.controls.email.updateValueAndValidity();
        }
    // If user is Premium...
    } else if (this.currentUser.isPremium) {
        // ...and if user typed something in the input field, then apply validitor for email address
        if (this.myForm.controls.email.value.length > 0) {
            this.myForm.controls.email.setValidators([validateEmail()]);
            this.myForm.controls.email.updateValueAndValidity();
        // If user leaves the input field blank or empty the typed input, then remove any validator
        } else {
            this.myForm.controls.email.setValidators(null);
            this.myForm.controls.email.updateValueAndValidity();
        }
    }

    // SECOND PART
    // If the input field is valid then check if the email already exist on server...
    if (this.myForm.controls.email.value.length > 0 && this.myForm.controls.email.valid) {
        this.loadingIcon = true;
        this.anagraficaService.getEmail(this.myForm.controls.email.value)
            .then(response => {
                let count = response.recordCount;
                if (count > 0) {
                    this.found = true;
                } else {
                    this.found = false;
                }
                this.loadingIcon = false;
            })
            .catch(error => {
                this.found = false;
                this.loadingIcon = false;
            });
    }
}

To enable the Submit button in the template file, I check for myForm.valid and for found set to false:

<button type="submit" class="ui primary button" (click)="onSubmit()" [disabled]="!myForm.valid || found">Submit</button>

Now, i would like to check for email address if already exists, I mean put the second part of my code in an external file (custom Validator) and then check for email address validity only in the first part of my code. Something like this:

this.myForm.controls.email.setValidators([validateEmail(), checkEmailExists()]);
this.myForm.controls.email.updateValueAndValidity();

Do you have a better idea to reach the same verifications? Any best practice about this problem?

Thank you.


回答1:


Wow. That's far away from the idea of reactive forms validations.

First of all don't do this

this.myForm.controls.email.setValidators([validateEmail()]);
this.myForm.controls.email.updateValueAndValidity();

setValidators and updateValueAndValidity are the functions you should nearly never call. They are available only for some specific cases like dynamic form behaviour.

In your case you have a static form which you should just describe with some validators. Create a custom asynchronous validator and assign it to the email FormControl. This validator should return an Observable (or a Promise) which resolves either to null when everything is fine or to an object with an error, e.g. { emailAlreadyExists: true } if email exists, { required: true } or use a combination of Validators.required and your custom async validation.

In the end of the day you should have

...
public ngOnInit() {
  this.myForm = new FormGroup({
    email: new FormControl('', null, (control: FormControl) => {
      return new Promise((resolve, reject) => {
        // also add here is premium logic
        let requiredValidationResult = Validators.required(control);

        if (requiredValidationResult) {
          resolve(requiredValidationResult); // this will be {required: true}
          return;
        }

        // and here call your server and call
        //   resolve(null) in case it's fine
        //   resolve({ emailExists: true }) in case it's existing
      });
    })
  });
}
...

and that's it.



来源:https://stackoverflow.com/questions/41847285/angular2-email-already-exist-as-custom-validator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!