//

Different ways of unsubscribing from RxJS Observables with Angular

23.1.2018 | 2 minutes of reading time

Angular uses RxJS as a backbone of the Angular application. RxJS uses the concept of Observables and Observers, where an Observable is a source of data and Observer is the one who use the data. Every time an Observable produces new values, it informs an Observer and the Observer handles those values inside subscribe operator. Dealing with Observables can be dangerous because there is the possibility of creating a memory leak. How’s that even possible?

Problem

Every time a component/directive is destroyed, all subscriptions to custom Observables still remain active.

Solution

Manually unsubscribe from all custom Observables when a component/directive gets destroyed. The best place to unsubscribe is inside functions that handle the OnDestroy lifecycle hook. Some subscriptions like router and http don’t need manual unsubscribe, for the rest of them there are various solutions:

  • execute unsubscribe over the subscription object
  • using takeUntil operator
  • using async pipe

Unsubscribe

1export class UnsubscribeCardComponent implements OnInit, OnDestroy {
2  message: string;
3  subscription: Subscription;
4  constructor(private upperCaseService: UpperCaseService) {}
5 
6  ngOnInit() {
7    this.subscription = this.upperCaseService.getUpperCaseMessage()
8      .subscribe((message: string) => this.message = message);
9  }
10 
11  ngOnDestroy(): void {this.subscription.unsubscribe();}
12}
13

Subscription represents a disposable resource, it has an unsubscribe method that can be used to dispose the resource held by the subscription.

TakeUntil

1export class TakeUntilCardComponent implements OnInit, OnDestroy {
2  message: string;
3  private unsubscribe$ = new Subject();
4  constructor(private upperCaseService: UpperCaseService) {}
5 
6  ngOnInit() {
7    this.upperCaseService.getUpperCaseMessage()
8      .takeUntil(this.unsubscribe$)
9      .subscribe((message: string) => this.message = message);
10  }
11 
12  ngOnDestroy(): void {
13    this.unsubscribe$.next();
14    this.unsubscribe$.complete();
15  }
16}
17

TakeUntil takes a second Observable as an argument, it monitors the second Observable and discard subscription after it emits a value or terminates.

AsyncPipe

1export class AsyncPipeCardComponent implements OnInit {
2  messageSubscription: Observable<string>;
3  constructor(private upperCaseService: UpperCaseService) {}
4 
5  ngOnInit() {
6    this.messageSubscription = this.upperCaseService.getUpperCaseMessage();
7  }
8}
9
1<h4 class="card-title">{{messageSubscription | async}}</h4>
2

The async pipe subscribes to an Observable and returns the latest value it has emitted. When a component is destroyed, the async pipe unsubscribes automatically.

Conclusion

When a component/directive is destroyed, all custom Observables need to be unsubscribed manually. Async pipe is a good solution, because it does everything automatically, but keep in mind that it can’t be used in all scenarios.
The RxJS lead developer Ben Lesh recommends the takeUntil approach. He explains his arguments in this article.

The sourcecode for the complete example can be found here.
The demo example can be found here.

share post

Likes

0

//

More articles in this subject area\n

Discover exciting further topics and let the codecentric world inspire you.

//

Gemeinsam bessere Projekte umsetzen

Wir helfen Deinem Unternehmen

Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.

Hilf uns, noch besser zu werden.

Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.