Unsubscribing from Observables in Angular

Jacob Neterer
4 min readMay 10, 2020

You’ve probably heard a lot about RxJs, and more than likely used it in your Angular applications. If so, have you learned how to unsubscribe from observables? Do you know why it is important to do so? Not doing so ended up biting me in the butt. Read ahead for several simple ways on how you can properly unsubscribe from observables! You can also see these techniques in action here in this Stackblitz project.

Why is this important?

When I was first learning Angular and RxJs, I was having trouble understanding RxJs, and thus wrote this off. By unsubscribing from observables, you will prevent memory leaks and errors, which can be extremely difficult to debug. What kind of errors might this cause? Take into account the below example:

ngOnInit() {
this.observable.subscribe((value) => {
// important logic on app state, modification of DOM, etc.
});
}

What happens to this observable when the component is no longer rendered in the DOM? If the observable is fired, will the code here still run? The answer is, yes, it does. If this observable triggers logic like manipulating the DOM, you might see errors when the code tries accessing HTML elements that are no longer rendered. If it triggers business logic, you might see incorrect data throughout the application. That is extremely difficult to debug, and what makes unsubscribing from observables so important. You can see in the gif below that the observable continues to fire, even after the component has been removed from the DOM.

We can fix this issue using any of the following examples!

unsubscribe()

Using unsubscribe() is the traditional, out-of-the-box method for unsubscribing from observables. This technique is useful when you want to set the observable to a variable, or if you only have one observable in your component that you subscribe to. Take the following observable:

this.someObservable = interval(1000).subscribe((value) => {
console.log('value: ', value);
});

It fires a number, starting from 0, and increases by an increment of 1 every second. In order to unsubscribe from this observable we can simply call unsubscribe() on the observable in ngOnDestroy. Why in ngOnDestroy? That is the lifecycle hook that gets fired when the component is being destroyed.

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

take(n)

This technique, take(n), is another great way of unsubscribing from observables. It is especially useful when you only want to subscribe a specific number of times. Using the same observable, we can simply use the take operator and provide n number of events we want to subscribe to. Here we only want to subscribe up to 5 times the observable fires.

this.someObservable = interval(1000).pipe(take(5))
.subscribe((value) => {
console.log('value: ', value);
});

Using this technique we don’t need to call unsubscribe() in ngOnDestroy. I should caution you, however, to ensure you choose a number of times you know the observable will fire. If there is no guarantee, you should unsubscribe as we did in the first example in order to properly clean up the observable, in case it does not fire that many times.

takeUntil(x)

Last (in this article), but certainly not least, is takeUntil(x). This technique is useful when you have several observables you subscribe to, and you want to unsubscribe from them all at once. For this we will need a subject to help us unsubscribe when the component is destroyed. The subject is defined as follows:

private unsubscribe: Subject<any> = new Subject<any>();

Make sure the unsubscribe subject is private so it can’t be accessed outside of this component. Using a variation of the previous observables, we will directly subscribe to the observables and not set them to a variable in the component. The first is fired every half second and the second is fired every second. You will see that we are making use of the unsubscribe subject by passing it to the takeUntil operator. Here are the observables we are subscribed to:

interval(500).pipe(takeUntil(this.unsubscribe))
.subscribe((value) => {
console.log('observable 1: ', value);
});
interval(1000).pipe(takeUntil(this.unsubscribe))
.subscribe((value) => {
console.log('observable 2: ', value);
});

To unsubscribe from both of these observables at once when the component is destroyed, in ngOnDestroy we simply call next() with no value and complete() to complete the subject.

ngOnDestroy() {
this.unsubscribe.next();
this.unsubscribe.complete();
}

Final Thoughts

There are many useful and creative ways to unsubscribe from observables in your Angular application. These three ways give you a great start. Do you have your own, unique way of unsubscribing from observables? Tell us about it in the comments below! Don’t forget you can check out the code for these techniques here in this StackBlitz project! Thanks for reading!

You can find me on Twitter, GitHub, LinkedIn, and my website!

--

--

Jacob Neterer

Lead software engineer specializing in web and mobile development. Always learning new things. “There is no growth in the comfort zone…”