I've created a custom Async validator that uses a service to validate emails against a server. However, this means the server is hit every time a character is entered which is no good. I've followed several answers on here that I haven't been able to get working.
My Validator:
import {FormControl, NG_ASYNC_VALIDATORS, Validator} from
'@angular/forms';
import { Http } from '@angular/http';
import {Directive, forwardRef} from "@angular/core";
import {ValidateEmailService} from "../services/validate-email.service";
import {UserService} from "../services/user.service";
@Directive({
selector: '[appEmailValidator]',
providers: [
{ provide: NG_ASYNC_VALIDATORS, useExisting: forwardRef(() => EmailValidator), multi: true }
]
})
export class EmailValidator implements Validator {
public validateEmailService: ValidateEmailService;
constructor(
private _http: Http,
private _userService: UserService
) {
this.validateEmailService = new ValidateEmailService(this._http, this._userService);
}
validate(c: FormControl) {
return new Promise(resolve => {
this.validateEmailService.validateEmail(c.value)
.subscribe((res) => {
console.log(res);
if (res.valid) {
resolve(null);
} else {
resolve({
valid: {
valid: false
}
});
}
});
})
}
}
It works well by itself but as soon as I try to add some form of debounce to it, I end up breaking it.
I've tried the answers from this question and I get errors along the lines of Type X is not assignable to type 'Observable<any>'
etc.
I got close by using a setTimeout
but all that ended up doing was halting the functionality.
My end goal is to only run the validator when the input hasn't been changed for about 600 ms, but would settle for only validating once every 600-2000 ms.
For additional clarity, the validateEmail
method from the ValidateEmailService
:
public validateEmail(email: string) {
let validateEmail = new ValidateEmail(email);
return this._http.get(
this.getUrl(validateEmail),
this.getOptionArgs())
.map((response: Response) => Object.assign(new UserEmailVerification(), response.json().UserEmailVerification));
}