Issue
I've been trying to add an async validator in my Angular application to check the validity of the email, with a new form all works as expected, the issue comes when I'm editing the form, so the value is prefilled, after the page load, the status of the email control remains in pending.
If the email is the same of the load one, the validator must return no errors as it means that the email has not been changed.
I've tried to add .updateValueAndValidity()
or to set the validator manually after I load the data but nothing worked.
The console.log()
returns correctly the data for both value
and this.user?.email
form: FormGroup = new FormGroup({
email: new FormControl(null, {
validators: [Validators.required, Validators.email],
asyncValidators: [this.validateEmail()]
}),
username: new FormControl(null, Validators.required),
role: new FormControl(null, Validators.required),
});
ngOnInit(): void {
this.getUser();
}
async getUser(): Promise<void> {
const response = await this.service.getUser(this.userId);
if (response.error) this._snackBar.open('Errore durante il caricamento dei dati!', 'OK', { panelClass: 'error' });
else {
this.user = response.data as Profile;
this.getCompanies();
this.form.setValue({ email: this.user?.email, username: this.user?.username, role: this.user.role.id });
}
this.isLoading = false;
}
validateEmail(): AsyncValidatorFn {
return control => control.valueChanges.pipe(
debounceTime(400),
distinctUntilChanged(),
switchMap(value => {
if (value === this.user?.email) {
console.log(value, this.user?.email);
return of(null)
}
return this.service.checkEmail(value).pipe(
map(exists => exists ? { exists: true } : null),
catchError(() => of(null))
)
}),
first());
}
Solution
I've resolve the issue by moving out of the pipe the check for the control value and current email.
validateEmail(): AsyncValidatorFn {
return control => {
if (!control.valueChanges) {
return of(null)
}
if (control.value === this.user?.email) {
return of(null)
}
return control.valueChanges.pipe(
distinctUntilChanged(),
switchMap(value => {
return this.service.checkEmail(value).pipe(
map(exists => exists ? { exists: true } : null),
catchError(() => of(null))
)
}),
first());
}
}
Btw I'm still interested in alternative solutions inside that switchMap
.
Answered By - NiceToMytyuk
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.