I have seen the following code in an angular application. In the code, a Subscription
is being used to subscribe
and unsubscribe
. I don't understand why a Subscription
is used. Is there any benefit in using this pattern?
public routeChangeSub$: Subscription;
this.routeChangeSub$ = this.route.firstChild.paramMap
.subscribe((map: ParamMap) =>
this.getRouteParams(map));
this.routeChangeSub$.unsubscribe();
getRouteParams(map: ParamMap): number {
const characterId = map.get('id');
let id: number = null;
if (characterId) {
this.character$ = this.store.pipe(
select(selectCharacterById, { id: characterId })
);
id = parseInt(characterId, 10);
}
return id;
}
Update:
How this can be different from
this.route.firstChild.paramMap
.subscribe((map: ParamMap) =>
this.getRouteParams(map));
getRouteParams(map: ParamMap): number {
const characterId = map.get('id');
let id: number = null;
if (characterId) {
this.character$ = this.store.pipe(
select(selectCharacterById, { id: characterId })
);
id = parseInt(characterId, 10);
}
return id;
An observable (which is the type of route.firstChild.paramMap
) will not emit anything unless something is subscribed to it.
In this file, the author explicitly subscribes to paramMap
to trigger a state change by calling getRouteParams()
. Then they immediately unsubscribe. If they didn't unsubscribe, the subscription will continue to run which may cause state issues and memory leaks.
A far simpler solution is to use the take(1)
operator. This will take an emitted value (the 1
is the number of values to take) then will send a complete
signal to the subscription. This causes the subscription to automatically unsubscribe.
this.route.firstChild.paramMap.pipe(
take(1),
tap(map=>this.getRouteParams(map))
).subscribe();
Because we're using take()
, we don't need to assign the subscription to a property. The observable will emit one value, and will invoke getRouteParams()
before unsubscribing.
Note: If you're not aware, tap()
is the operator to use if you want to apply an effect to any state property outside of the observable.