Does there exist something equivalent to the async
pipe that I could use inside a component like this
@Component({
selector: \'my-component
No there's not. You need to manually subscribe and manually unsubscribe to avoid memory leaks.
For a simple subscription you may be tempted to do :
@Component({
selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
public myObservable$: Observable;
private myObservableSub: Subscription;
ngOnInit() {
this.myObservableSub = this
.myObservable$
.subscribe(_ => {
// do something
});
}
ngOnDestroy() {
this.myObservableSub();
}
}
But what if you have many subscribe ? Should you do something like :
@Component({
selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
public myObservable1$: Observable;
private myObservableSub1: Subscription;
public myObservable2$: Observable;
private myObservableSub2: Subscription;
public myObservable3$: Observable;
private myObservableSub3: Subscription;
ngOnInit() {
this.myObservableSub1 = this
.myObservable1$
.subscribe(_ => {
// do something
});
this.myObservableSub2 = this
.myObservable2$
.subscribe(_ => {
// do something
});
this.myObservableSub3 = this
.myObservable3$
.subscribe(_ => {
// do something
});
}
ngOnDestroy() {
this.myObservableSub1();
this.myObservableSub2();
this.myObservableSub3();
}
}
Upadted reply (16/11/20)
In the original answer (see after this edit), I do avise to use take until but this forces you to create a subject and trigger an event into it when the component is destroyed. While the idea behind this is good, it's quite a lot of boilerplate to put in all the components where we subscribe to a stream.
Instead of this, we can create a custom operator that we can call takeUntilDestroyed
and do something like this:
@Component({
selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
public myObservable1$: Observable; // define your observable
public myObservable2$: Observable; // define your observable
public myObservable3$: Observable; // define your observable
ngOnInit() {
this
.myObservable1$
.pipe(takeUntilDestroyed(this))
.subscribe(_ => {
// do something
});
this.myObservableSub2 = this
.myObservable2$
.pipe(takeUntilDestroyed(this))
.subscribe(_ => {
// do something
});
this.myObservableSub3 = this
.myObservable3$
.pipe(takeUntilDestroyed(this))
.subscribe(_ => {
// do something
});
}
ngOnDestroy() {}
}
The implementation of this custom operator can be found here: https://github.com/cloudnc/ngx-sub-form/blob/1115b21a007f72c54b521b3bed7c40051302145a/projects/ngx-sub-form/src/lib/shared/ngx-sub-form-utils.ts#L145-L148
Original reply
You should rather do the following :
@Component({
selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
private componentDestroyed$ = new Subject();
public myObservable1$: Observable;
public myObservable2$: Observable;
public myObservable3$: Observable;
ngOnInit() {
this
.myObservable1$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
this
.myObservable2$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
this
.myObservable3$
.takeUntil(componentDestroyed$)
.subscribe(_ => {
// do something
});
}
ngOnDestroy() {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
}
}
If you want to know more about that, here's an excellent article from Ben Lesh : https://medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87
EDIT :
Thanks to @olsn, I edited my answer and added the line with the next
because indeed a complete doesn't stop the others streams.
I created a small Plunkr to demo that behaviour : https://plnkr.co/edit/dcueDqUgpqgYimxEAGUn?p=preview