I have a subscribe call that needs to only receive data once. The Angular 2 page that its on is long running.
I want to ensure that the subscription doesn't cause any problems regarding memory leaks and unsubscribes once data is received the first time.
This is my service that makes an api query. It uses .first so it should cleanup once data is received once.
getData(): Observable<string> {
let _url = SOME_API_URL;
return this._http.get(_url).first().map((response: Response) => { return response.json(); });
}
This is my Ng2 subscription. Do I need to do anything in this is ensure that everything is cleaned up after the first() data is received?
this._service.getData().subscribe((data: any) => {
// Do something once.
// DO I HAVE TO UNSUBSCRIBE OR WILL THE CLEANUP HAPPEN DUE TO THE ABOVE FIRST() CALL?
});
I could use ngDestory but that wouldn't be called as the page is long running and is not often refreshed.
A fundamental aspect of observables is that when they complete, any subscriptions are automatically unsubscribed. As such, if you know an observable will complete then you do not need to worry about cleaning up any subscriptions.
🎩 Automagically Unsubscribe in Angular As you probably know when you subscribe to an observable or event in JavaScript, you usually need to unsubscribe at a certain point to release memory in the system. Otherwise, you will have a memory leak. A memory leak occurs when a section of memory that is no longer being…
These are called “finite subscriptions”. If you subscribe with a “take(1)”, as another example, it is finite and doesn't need to be unsubscribed. This is easy enough to test out if you are unsure of it being finite or infinite. For example, you could console.
first
won't subscribe to the Observable
for you.
For example, if you do this :
Rx
.Observable
.of(1, 2, 3)
.first()
.map(x => console.log(x))
<script src="https://npmcdn.com/[email protected]/bundles/Rx.umd.js"></script>
Nothing happen.
So, you need to subscribe
to that Observable
... And who says subscribe
says that you need to unsubscribe
from it yourself.
let subscription = Rx
.Observable
.of(1, 2, 3)
.first()
.map(x => console.log(x))
.subscribe(
(success) => {},
(error) => {},
(done) => { console.log('unsubscribe') }
);
subscription.unsubscribe();
<script src="https://npmcdn.com/[email protected]/bundles/Rx.umd.js"></script>
Just save the subscription
in one of your class variable and implements onDestroy
method :
ngOnDestroy() {
this.subscription.unsubscribe();
}
Edit 1 :
Just to be more clear :
If you go through first()
, it'll be unsubscribed as you expect.
BUT, let say your observable is taking a very long time and you decide to move somewhere else in your app, and the component gets destroyed. The observable will remain alive (at least until it receives one value).
So you should still keep the ngOnDestroy
method in case your component is destroyed before the observable is unsubscribed.
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