0

I'm writing an asynchronous validator that checks uniqueness of title. If titles match then the backend throws and error, this should fire the validation.

component.ts:

constructor(
       public http:Http,
        private formBuilder: FormBuilder) {
            this.form = formBuilder.group({
                title: ['', Validators.required, uniqueTitle.bind(this)]
            });
} 

validator.ts

export function uniqueTitle(control: FormControl) : Observable<any> {
  let headers = new Headers();
  headers.append('Content-Type', 'application/json');

  return new Observable((obs: any) => {
    control
        .valueChanges
        .debounceTime(4000)
        .flatMap(value => this.http.get('http://localhost:3001/api/v1/academic_terms/show_by_title?title=' + control.value, {headers}))
        .subscribe(
            data => {
                obs.next(null);
                obs.complete();
            },
            error => {
                let message = error.json().errors;
                let reason;

                if (message === 'Title Taken') {
                    reason = 'validateTitle';
                }
                obs.next({ [reason]: 'Title has already been taken' });
                obs.complete();
            }
        );
  });
}

This works fine, but if I quickly type any title with say 10 chars then the debounce will wait (4 seconds in this case ... for testing) and it will then hit the server 10 times.

  • A
  • AB
  • ABC
  • etc

Am I missing something here? I read that it might have something to do with the fact that I'm not returning an observable but I can't make sense of it.

Mark Kenny
  • 1,598
  • 2
  • 17
  • 30
  • 1
    http://stackoverflow.com/questions/36919011/how-to-add-debounce-time-to-an-async-validator-in-angular-2 you'll need to implement a workaround – silentsod Dec 08 '16 at 17:37
  • Thanks for pointing that out @silentsod. There seems to be issues with debouncing Observables with asynchronous validators. From this I reverted to using a Promise with the setTimeout() as suggested in the post above by izupet and now only one call is made. – Mark Kenny Dec 08 '16 at 18:05
  • No problem, I'll flag this as a dupe so if someone comes across this question they'll find the other I linked. – silentsod Dec 08 '16 at 18:06

0 Answers0