Reputation:
i have multiple functions that have subscriptions. First i have it on the ngOnInit(), then i have another function called onSelectVillain(). So my question is this possible that you could just use this.subscription.unsubscribe(). Or should i make declare another subscription?
subscription: Subscription;
ngOnInit() {
this.subscription = this.heroService.getHeroes()
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error);
}
onSelectVillain(event) {
this.subscription = this.villainService.getVillains()
.subscribe(
.....
}
ngOnDestroy(){
this.subscription.unsubscribe()
}
Upvotes: 1
Views: 2907
Reputation: 222389
Once subscription
value is replaced, previous subscription is lost, it's no different than any other value.
A cleaner way is to have different subscriptions that have meaningful names - heroesSubscription
, villainsSubscription
, etc:
heroesSubscription: Subscription;
villainsSubscription: Subscription;
ngOnInit() {
this.heroesSubscription = this.heroService.getHeroes().subscribe(...);
}
onSelectVillain(event) {
// possibly needs to unsubscribe previous subscription
if (this.villainsSubscription)
this.villainsSubscription.unsubscribe()
this.villainsSubscription = this.villainService.getVillains().subscribe(...)
}
ngOnDestroy(){
this.heroesSubscription.unsubscribe()
this.villainsSubscription.unsubscribe()
}
If it's possible that onSelectVillain
is called multiple times, previous subscription should be unsubscribed.
The code doesn't show the benefits of doing subscriptions manually. When observable values are consumed only in view, async
pipe can be used instead because it does all subscription/unsubscription work automatically:
{{ heroService.getHeroes() | async }}
Upvotes: 1
Reputation: 175
It would be cleaner to use a seperate subscription - and if you use the same field you would never (manually) unsubscribe from the first subscription. Also if you don't want to clutter your component with lots of fields, that simply hold subscription references I would recommend to use a pattern, that involves using just one Subject, that is triggered at ngOnDestroy and before each subscribe you would use takeUntil. So your code could look like this:
private ngUnsubscribe = new Subject();
ngOnInit() {
this.heroService.getHeroes()
.takeUntil(this.ngUnsubscribe)
.subscribe(
heroes => this.heroes = heroes,
error => this.errorMessage = <any>error);
}
onSelectVillain(event) {
this.villainService.getVillains()
.takeUntil(this.ngUnsubscribe)
.subscribe(
.....
}
ngOnDestroy(){
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
See this for further reference.
Note that subscriptions that are "finite", so where a complete state is called, don't neccessarily need to get unsubscribed manually. This is probably a good reference point for that.
Upvotes: 3