问题
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