I have a working async validator that does an HTTP request to the server to check if a username is already taken. As I don't want to call the API after each keystroke I need to debounce the input stream.
I first had throttleTime
in the service, but another topic on SO said this has to be on the one who subscribes, but no luck yet!
My Component:
this.form = this._fb.group(
{
username: ['', [Validators.required, Validators.maxLength(50), NoWhitespaceValidator], [IsUserIdFreeValidator.createValidator(this._managementService)]]
});
My Validator:
export class IsUserIdFreeValidator {
static createValidator(_managementService: ManagementService) {
return (control: AbstractControl) => {
return _managementService.isUserIdFree(control.value)
.pipe(
throttleTime(5000),
(map(
(result: boolean) => result === false ? { isUserIdFree: true } : null))
);
};
}
}
My Service:
public isUserIdFree(userId: string): Observable<{} | boolean | HttpError> {
const updateUserCheck: UpdateUserCheck = new UpdateUserCheck();
updateUserCheck.userID = userId;
return this._httpClient.post<boolean>('UserManagementUser/IsUserIdFree', updateUserCheck));
}
I was able to solve this trough another way, via a propery called 'updateOn' on the control.
With template-driven forms:
<input [(ngModel)]="name" [ngModelOptions]="{updateOn: 'blur'}">
With reactive forms:
new FormControl('', {updateOn: 'blur'});
If you use the form-builder, since Angular 7 you can use this:
this.form = this._fb.group({
email: ['', [CustomValidators.email], null, 'blur'],
});