2

I have been trying to interpret this article but with newer RxJS the needed syntax has changed. There is something I don't get. My working AsyncValidator's validate method looks like this:

  validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
    return Observable.create(resolve => {
      const pathname = control.value;
      if (!pathname || pathname.length < 1) { resolve(null);  return; }
      this.client.pathCheck(this.parentPath + '/' + pathname).subscribe(
        resp => resolve.next(resp.inuse ? { pathInUse: true } : null),
        err => resolve.next(null),
        () => resolve.complete(null)
      );
    });
  }

What I don't understand is how to fit in the timer, pipe, and switchMap functions to replace the Observable.create.

What I also don't understand is why the debounce pipe isn't used for this.

Any help much appreciated.

Dino
  • 7,779
  • 12
  • 46
  • 85
AlanObject
  • 9,613
  • 19
  • 86
  • 142
  • there is an answer using debounceTime, I would definitely do it using debouncetime. It makes no sense also to wrap all code in an new observable. So I would definitely suggest the following: https://stackoverflow.com/a/57009006/6294072 – AT82 Sep 09 '19 at 10:34

1 Answers1

1

Here is how it should be done with RxJS 6 - Using timer, pipe and switchMap

validate(control: AbstractControl): Promise < ValidationErrors | null > | Observable < ValidationErrors | null > {
    return timer(1000).pipe(
        switchMap(() => {
            const pathname = control.value;
            if (!pathname || pathname.length < 1) {
                return of(null);
            }
            return this.client.pathCheck(this.parentPath + '/' + pathname).pipe(
                map((res) => {
                    return resp.inuse ? { pathInUse: true } : null;
                })
            )
        })
    )
}

Bear in mind that Validators return either null if the FormControl is valid or an error object if it’s not. It seems that you are doing the opposite in your approach. Example:

if (!pathname || pathname.length < 1) {
    return of(null);
}

This will set the FormControl as valid. You might want to change that to something like this:

if (!pathname || pathname.length < 1) {
    return of({emptyPath: true});
}

Stackblitz

Dino
  • 7,779
  • 12
  • 46
  • 85
  • thanks for this answer. I do have one outstanding question: When a second call to `validate` comes in and a new Observable is generated, what happens to the old one that is still waiting for `timer` to be expired? Looking at the result it seems to get cancelled but I don't understand how. – AlanObject Sep 09 '19 at 21:58