Ben Cameron
Ben Cameron

Reputation: 4413

Angular2 and RXJS, unsubscribe after data received once

I have a subscribe call that needs to only receive data once. The Angular 2 page that its on is long running.

I want to ensure that the subscription doesn't cause any problems regarding memory leaks and unsubscribes once data is received the first time.

This is my service that makes an api query. It uses .first so it should cleanup once data is received once.

getData(): Observable<string> {
    let _url = SOME_API_URL;
    return this._http.get(_url).first().map((response: Response) => { return response.json(); });
}

This is my Ng2 subscription. Do I need to do anything in this is ensure that everything is cleaned up after the first() data is received?

this._service.getData().subscribe((data: any) => {
    // Do something once.
    // DO I HAVE TO UNSUBSCRIBE OR WILL THE CLEANUP HAPPEN DUE TO THE ABOVE FIRST() CALL?
});

I could use ngDestory but that wouldn't be called as the page is long running and is not often refreshed.

Upvotes: 8

Views: 9769

Answers (1)

maxime1992
maxime1992

Reputation: 23793

first won't subscribe to the Observable for you.

For example, if you do this :

Rx
  .Observable
  .of(1, 2, 3)
  .first()
  .map(x => console.log(x))
<script src="https://npmcdn.com/[email protected]/bundles/Rx.umd.js"></script>

Nothing happen.

So, you need to subscribe to that Observable ... And who says subscribe says that you need to unsubscribe from it yourself.

let subscription = Rx
  .Observable
  .of(1, 2, 3)
  .first()
  .map(x => console.log(x))
  .subscribe(
    (success) => {},
    (error) => {},
    (done) => { console.log('unsubscribe') }
  );

subscription.unsubscribe();
<script src="https://npmcdn.com/[email protected]/bundles/Rx.umd.js"></script>

Just save the subscription in one of your class variable and implements onDestroy method :

ngOnDestroy() {
  this.subscription.unsubscribe();
}

Edit 1 :

Just to be more clear :

If you go through first(), it'll be unsubscribed as you expect.

BUT, let say your observable is taking a very long time and you decide to move somewhere else in your app, and the component gets destroyed. The observable will remain alive (at least until it receives one value).

So you should still keep the ngOnDestroy method in case your component is destroyed before the observable is unsubscribed.

Upvotes: 11

Related Questions