In Angular 2 there are some observables that you do not need to unsubscribe from. For example http requests and activatedRoute.params.
Angular/RxJs When should I unsubscribe from `Subscription`
But what happens when I use switchMap on for example activatedRoute.params and inside that switchMap I access a service that returns an observable that would need to be unsubscribed if subscribed to in the usual way.
Something like this:
this.activatedRoute.params
.switchMap((params: Params) => this.userService.getUser(+params['id']))
.subscribe((user: User) => this.user = user);
If I called this.userService without the switchMap and without activatedRoute.params I would have to unsubscribe from it.
// userService.getUser() takes in optional id?: number.
this.subscription = this.userService.getUser().subscribe(
(user: User) => {
this.user = user;
}
);
And then later..
this.subscription.unsubscribe();
My question is, do I need to unsubscribe from activatedRoute.params if I use switchMap on it and call a service that would need to be unsubscribed otherwise?
The SwitchMap creates a inner observable, subscribes to it and emits its value as observable.
Once the higher-order observable emits a new value, switchMap executes the function to get a new inner observable stream and switches the streams. It unsubscribes from the current stream and subscribes to the new inner observable. The operator works in the following way: Subscribe to a higher-order source observable.
No need to unsubscribe from internal observables of an application scoped service since this service never get's destroyed, unless your entire application get's destroyed, there is no real reason to unsubscribe from it and there is no chance of memory leaks.
In Angular applications, it's always recommended to unsubscribe the observables to gain benefits like: Avoids Memory Leaks. Aborting HTTP requests to avoid unwanted calls.
If the source observable to which you are subscribing always completes or errors, you don't need to unsubscribe.
However, if you compose another observable from the source using switchMap
, whether or not you need to unsubscribe depends upon the observable returned within switchMap
. If the returned observable does not always complete or error, then, yes, you will need to unsubscribe.
If the source errors, an automatic unsubscription will occur:
const source = new Rx.Subject();
const composed = source.switchMap(() => Rx.Observable.interval(200));
composed.subscribe(value => console.log(value));
source.next(1);
setTimeout(() => {
console.log("Erroring...");
source.error(new Error("Boom!"));
}, 1000);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/[email protected]/bundles/Rx.min.js"></script>
However, if the source completes, an automatic unsubscription will not occur:
const source = new Rx.Subject();
const composed = source.switchMap(() => Rx.Observable.interval(200));
composed.subscribe(value => console.log(value));
source.next(1);
setTimeout(() => {
console.log("Completing...");
source.complete();
}, 1000);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://unpkg.com/[email protected]/bundles/Rx.min.js"></script>
switchMap
creates a link between the previous and new observable. If you change the first observable, the second will be always be triggered.
Anything subscribed after the switchMap
will be hearing changes on both, the initial observable and the returned observable.
To fully stop the first observable to update the second one or the rest is by using take
, takeUntil
, or takeWhile
. Like:
const howTimerWorks = interval(5000).pipe(
take(2), // only get 2 responses after 5 seconds each
switchMap(initialNumber => interval(1000)));
// 0 after 5s, then 1, 2 , 3, (new Subs) 0, 1, ... every sec, forever now.
howTimerWorks.subscribe(console.log)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With