As described in this thread, 'official' solution to unsubscribe from Observables in Angular 5+ in general is using takeUntil. So far, so good. My question is, does this also apply if the Observable I am subscribed to is actually a Subject?
-
2Yes, it doesn't matter because `Subject` extends `Observable` class. This applies to `EventEmitter` as well because it extends `Subject` class. – martin May 31 '18 at 17:03
-
1as martin said, yes. Basically anytime you subscribe to something, you should destroy that subscription (unsubscribe) at some point in time, to avoid memory leaks, no matter what you are subscribing to. – David Anthony Acosta May 31 '18 at 17:18
-
To add to above, OnDestroy is a great thing to implement for destroying subscriptions in components. http://brianflove.com/2016/12/11/anguar-2-unsubscribe-observables/ – ShellNinja May 31 '18 at 17:35
-
1Also, put takeUntil as last operator to avoid messing up the unsubscribe: https://blog.angularindepth.com/rxjs-avoiding-takeuntil-leaks-fb5182d047ef – Davy Jun 01 '18 at 12:40
2 Answers
Once you call .subscribe()
on anything (subjects too), something needs to make sure the subscription gets unsubscribed.
Dealing with the finite Observables: If you subscribe to a finite observable (meaning an observable that has a finite/limited sequence), the last message will send an end signal and the subscription will be canceled automatically. Examples of this are:
Observable.of(100)
Observable.from([1,2,3,4])
Examples of infinite observables are:
Observable.fromEvent(document, 'click')
Observable.timer(1000)
Calling/piping .first()
, .take(number)
or .takeWhile(condition that will evaluate to false at some point)
or takeUntil(observable that emits a value)
on an observable will all turn an otherwise infinite observable into a finite one.
Stop calling .subscribe(): Another popular method of not having to unsubscribe is by not subscribing in the first place. This might sound stupid, since when would you want an observable that you do not subscribe to? Well if you only need to pass some data to your view/HTML template, piping that observable into the async pipe will pass the unsubscribing issue to the async pipe itself.
Typical examples in the HTML template:
<h1>Editing {{ infiniteObservable$ | async }}<h1>
<li *ngFor="let user of userObservable$ | async as users; index as i; first as isFirst">
{{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
</li>
Manually unsubscribing: Lastly, you can choose to keep references to all subscriptions. You don't have to keep a variable pointing to each subscription, it's easier to just use a single Subscription object to keep track of all the subscriptions, and then unsubscribe to all of them at once. Here is an example:
const subscriptions = new Subscription();
subscriptions.add(observable1$.subscribe());
subscriptions.add(observable2$.subscribe());
subscriptions.unsubscribe();
Quick summarize, how to handle unsubscriptions, any of the below methods:
- Turn infinite observables into finite ones, hereby removing the need to unsubscribe (use
.takeUntil(this.destroyed$)
and dothis.destroyed$.next()
inngOnDestroy()
). - Avoid subscribing, and passing the observable through the
async
pipe. - Keep a reference to any subscriptions and call
.unsubscribe()
in thengOnDestroy()
method.
Personally I tend to only use one of the two first methods.

- 23,933
- 14
- 88
- 109

- 15,097
- 21
- 80
- 101
-
1Thanks for the info. Why would you use takeWhile() instead of takeUntil(), as read in the thread I pointed to? xxx – didgewind Jun 03 '18 at 16:13
-
1Oh it shouldn't matter, I guess takeUntil would be more standard as the boolean variable would start by being false (default) and flipped to true instead of the other way around. – Per Hornshøj-Schierbeck Jun 04 '18 at 07:37
-
@didgewind Both operators transform an infinite into a finite observable, which means you don't need unsubscribe. Pick the one you feel is easier to read (when you or someone else needs to maintain your code later) – Per Hornshøj-Schierbeck Jun 04 '18 at 10:18
-
@PerHornshøj-Schierbeck what if you want to `unsubscribe` from `activatedRoute` `queryParams` in `app.component.ts` just after one `subscription`? – candidJ Sep 24 '18 at 08:42
-
-
@kuldeep yes i think all the calls are (but atleast the common ones, like get/post), because it only triggers once and angular handles unsubscription afterwards – Per Hornshøj-Schierbeck Feb 12 '21 at 06:49
I have something to add. Subject
stores the subscribers internally (Observable
does too). If the Subject
is part of your component (created inside, stored as property or in a closure) the subject and it's subscriptions are garbage collected with the component itself.
But this is a special case and one should be very careful with it: everything must be contained in the component.
It is e.g. safe to not unsubscribe from a FormControl.valueChanges
observable if it is used in the component only.
But to be on the safe side, and don't want to think about it, just use takeUntil
.

- 11
- 1
-
1Can you please point me to some documentation that shows the cleanup of Angular components including unsubscribing from Subjects? – Stevy Jul 16 '20 at 11:22