Whenever posible we should resist the temptation to subscibe to our observables. If we want to acccess the observable values in our template, it is better to use the async pipe. The async pipe will handle the subscription lifecycle for us. We simple don't have to worry about unsubscribing.
But in those situations where we must subscribe to an observable in our component, we need to handle the unsubscribe ourselves.
The traditional way of unsubscribing is the keep a reference to the subcription and call unsubscibe in ngOnDestroy...
export class MyComponent implements OnInit, OnDestroy {
private numbersSubscription: ISubscription;
private lettersSubscription: ISubscription;
ngOnInit() {
this.numbersSubscription= of([1, 2, 3]).subscribe(numbers => {});
}
someMethodCalledLater() {
this.lettersSubscription= of(['a', 'b', 'c']).subscribe(letters => {});
}
ngOnDestroy() {
this.numbersSubscription.unsubscribe();
if(this.lettersSubscription) {
this.lettersSubscription.unsubscribe();
}
}
}
I've used this pattern many times but found that it gets unwieldy when you have a number of subscriptions. A better pattern is to use the takeUntil operator. Lets refactor the same situation...
export class MyComponent implements OnInit, OnDestroy {
private onDestroy = new Subject();
ngOnInit() {
this.numbersSubscription= of([1, 2, 3])
.takeUntil(this.onDestroy)
.subscribe(numbers => {});
}
someMethodCalledLater() {
this.lettersSubscription= of(['a', 'b', 'c'])
.takeUntil(this.onDestroy)
.subscribe(letters => {});
}
ngOnDestroy() {
this.onDestroy.next();
this.onDestroy.unsubscribe();
}
}
This looks simpler to my eyes. We can add any number of subscriptions and all we need to do is add .takeUntil(this.onDestroy) to each call.
Top comments (1)
this.onDestroy.unsubcribe()
is unecessary since it is only used intakeUntil
.takeUntil
have an internal unsubscribe.there's also no need to do a
.complete()
call like some does.a single
.next()
is enoughyou can read more about it here
twitter.com/Michael_Hladky/status/...
twitter.com/kreuzercode/status/123...