2

I came across this answer Angular/RxJs When should I unsubscribe from `Subscription` on how to stop a subscription using takeUntil(). The answer also states that

The secret sauce (as noted already by @metamaker) is to call .takeUntil(this.ngUnsubscribe) before each of our .subscribe() calls which will guarantee all subscriptions will be cleaned up when the component is destroyed.

I am however having problems understanding why one of my two examples does not stop the subscription. Here is a working example

My Service:

export class GpsService {
  gps: Observable<any>;
  private ngUnsubscribe: Subject<any> = new Subject<any>();
  constructor() { }
  startFakeGps = (): void => {
    // This example does not stop the subscription after calling stopGps().
    this.gps = Observable.timer(3000, 1000);
    this.gps.takeUntil(this.ngUnsubscribe);

    // This example stops the subscription after calling stopGps().
    // this.gps = Observable.timer(3000, 1000).takeUntil(this.ngUnsubscribe);
  }

  stopGps() {
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
  }
}

My component:

export class ButtonOverviewExample implements OnInit {

  constructor(private gspService: GpsService){

  }
  ngOnInit(){
    this.gspService.startFakeGps();
    this.gspService.gps.subscribe(data => {});
  }

  // stop gps after clicking a button 
  stopGps(){
    this.gspService.stopGps();
  }


}

Example 1:

    // This example does not stop the subscription after calling stopGps().
    this.gps = Observable.timer(3000, 1000);
    this.gps.takeUntil(this.ngUnsubscribe);

Example 2:

    // This example stops the subscription after calling stopGps().
    this.gps = Observable.timer(3000, 1000).takeUntil(this.ngUnsubscribe);

I thought that both examples are using takeUntil() before the actual subscription starts, and that they are the same. Why is it different behaviour on these examples? What am I missing?

Here is a working example

John
  • 10,165
  • 5
  • 55
  • 71

1 Answers1

4
this.gps = Observable.timer(3000, 1000);

create observable and save it in this.gps

this.gps.takeUntil(this.ngUnsubscribe);

create NEW observable, but this.gps is not change You need to combine creating observable and adding .takeUntil operator

this.gps = Observable.timer(3000, 1000).takeUntil(this.ngUnsubscribe);
Mixalloff
  • 827
  • 4
  • 10
  • 2
    Exactly, the rxjs operators don't mutate the underlying Observable, they create a new one that you have to store. So alternatively (but not great style) this would work: `this.gps = this.gps.takeUntil(this.ngUnsubscribe);` – magnattic Feb 20 '18 at 11:02
  • Thank you for your answer. After understanding that it creates a new observable, everything makes sense. – John Feb 20 '18 at 11:15
  • Be carefull, sometimes you must use flat arrow Observable.takeUntil(() => this.ngUnsubscribe).subscribe() – Eliseo Feb 20 '18 at 11:56