Search code examples
angularrxjsrxjs5

Why switchMap does not cancel previous observer?


I have method described in component (controller):

public requestPassportData(): void {
    const th = this;
    const data = {
      get_scanned_data: true
    };

    Observable.timer(0, 1000)
      .switchMap(() => this.requestMethods.requestPassportData(data))
      .takeWhile(() => {
        return (
          th.formRegister.currentForm().index == 1 ||
          th.formRegister.currentForm().index == 2 ||
          th.formRegister.currentForm().index == 3
        );
      })
      .subscribe(response => {});
}

If to call method requestPassportData() five times, it will send each second five request to server. Why switchMap does not cancel last observer?


Solution

  • Because every time you call requestPassportData() you'll create a new chain with new Observable.timer that has nothing to do with the previous calls.

    There are obviously multiple ways to solve this but you can for example do the following:

    private requestPasswordSubject$ = new Subject();
    
    private requestPassword = this.requestPasswordSubject$
      .switchMap(() => Observable.timer(0, 1000)
        .switchMap(() => this.requestMethods.requestPassportData(data))
        .takeWhile(() => {
          return (
             th.formRegister.currentForm().index == 1 ||
             th.formRegister.currentForm().index == 2 ||
             th.formRegister.currentForm().index == 3
          );
        });
      )
      .subscribe(response => {});
    
    public requestPassportData(): void {
      ...
      this.requestPasswordSubject$.next();
    }
    

    Actual implementation depends on what exactly you're trying to achieve but hopefully you get the point what is different to what you have now.