'DebounceTime emits all the events which was captred during the time
I need to write the async validator for the reactive form type in angular. I have implemented it trough promise. But the issue is the validator triggers for each keystroke it strike the server for every keystroke.For implementing the debounce i have implemented the setTimeout for the promise but the issue i faced is it triggers for after the certain millisecon i have defined. Finally I have implemented the Observable inside the promise to achive all debounceTime, But the issue i faced here is the debounceTime emits all the events. For example: If I type 'Prem' from input field the following code triggers the server for four time as timeout works.
If any issue in implemetation of the async validator please clarify me.
//Latest code
static hasDuplicateEmail(formControl: FormControl) {
return new Promise((resolve, reject) => {
return new Observable(observer =>
observer.next(formControl.value)).pipe(
debounceTime(600),
distinctUntilChanged(),
switchMap((value) => {
//server side
return MotUtil.fetch('checkForRegisterEmail', {e: formControl.value});
})
).subscribe((res) => {
return (JSONUtil.isEmpty(res)) ? resolve(null) : resolve({duplicate: true});
});
});
}
The debounceTime should work as mentioned in the Docs.
Solution 1:[1]
You are trying to approach it in a difficult way. Validator takes argument - AbstractControl. AbstractControl has property - valueChanges which return stream of changes in your formControl. So here you add debouceTime and later do other operations and finaly return this stream back to FormControl:
hasDuplicateEmail(control: AbstractControl) {
return control.valueChanges.pipe(
debounceTime(600),
switchMap(e =>
this.http.get('checkForRegisterEmail', {e}).pipe(
map((res: any) => JSONUtil.isEmpty(res) ? null : { duplicate: true })
)
)
)
}
As you notice I use HttpClient as it is the way you make HTTP calls in Angular (it is designed to work on streams rather then Promises)
Solution 2:[2]
emailValidator(/** params that you need inside switchMap */): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors | null> => {
return of(control.value).pipe(
delay(500), //for me works with delay, debounceTime are not working with asyncValidator
filter(email=> !!email), //length or another logic there is not emails with less than 10 characters
distinctUntilChanged(),
switchMap(/** as you need */),
map(exist => (exist ? {duplicate: true} : null)),
catchError(() => of(null))
);
};
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Julius Dzidzevi?ius |
| Solution 2 |
