Last active
October 26, 2024 08:18
-
-
Save Humberd/b033c2c4df3ac0eae9b466038a433635 to your computer and use it in GitHub Desktop.
Async Validator Wrapper for Angular 2 Reactive Forms.This wrapper lets you debounce your asyncValidator instead of on every keystroke
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AbstractControl } from "@angular/forms"; | |
import { Observable } from "rxjs/Observable"; | |
import { Subject } from "rxjs/Subject"; | |
export class QstAsyncValidatorWrapper { | |
/* | |
* Angular async validators are triggered on every key stroke. | |
* This function debounces triggering an async validator. | |
* | |
* How to use? | |
* Let's say you have a function which asynchronously validates an email: | |
* | |
* function asyncEmailValidator (c: AbstractControl): Observable<any> { | |
* return checkInRemote(); | |
* } | |
* | |
* In your Reactive Form Builder instead of doing this: | |
* | |
* email: new FormControl("", [ | |
* Validators.required | |
* ], [ | |
* asyncEmailValidator | |
* ]) | |
* | |
* Do this to debounce every 800ms: | |
* | |
* email: new FormControl("", [ | |
* Validators.required | |
* ], [ | |
* QstAsyncValidatorWrapper.debounce(asyncEmailValidator, 800) | |
* ]) | |
* | |
* */ | |
public static debounce(asyncValidator: (c: AbstractControl) => Observable<any>, | |
time: number = 500): (c: AbstractControl) => Observable<any> { | |
/*Starting a debouncing observable*/ | |
const subject: Subject<AbstractControl> = new Subject(); | |
const obs: Observable<any> = subject | |
.debounceTime(time) | |
.switchMap(abstractControl => asyncValidator(abstractControl)) | |
.share(); | |
/*Need to have at least 1 active subscriber, because otherwise | |
* the first `subject.next(c)` event won't be registered*/ | |
obs.subscribe(); | |
return (c: AbstractControl) => { | |
/*Every time this function is invoked by Angular I must inform a subject about it*/ | |
subject.next(c); | |
/*Need to take only one for every function invocation, | |
* because the subscription must complete. | |
* Otherwise Angular form state would be "PENDING"*/ | |
return obs.first(); | |
}; | |
} | |
} |
this should be a npm package! 👍 :)
Edit: I created a angular5-compatible version, and published it to npm as an exercise for myself (never published any npm packages before). Hope you don't mind.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
type of first argument is AsyncValidatorFn instead of (c: AbstractControl) => Observable.
It's not compatible with angular (4+) abstract control API. Check setAsyncValidators() method