Reputation: 1643
I am building an app using Angular. As part of it, I am making an API call every 1 min for continuous data. My code looks like.
ngOnInit() {
this.getRealTimeData();
}
intervalId : any
getRealTimeData() {
this.getChillerApiData()
clearInterval(this.intervalId);
this.intervalId = setInterval(() => {
this.getChillerApiData();
}, 1000);
}
getChillerApiData() {
this.api.getFirstChillerData()
.subscribe((first_data:any) => {
this.first_api_data = first_data;
console.log(this.first_api_data)
this.putPrimaryPumpData();
});
}
I am getting data every 1 min or whatever time interval I mention. But what is happening is when I leave the component and go on to another component, still I see API calls made regularly at specified interval (I can see the console logs). How do I stop that from happening? I mean once I leave this component API calls should also stop.
Upvotes: 1
Views: 2798
Reputation: 31105
Use OnDestroy()
lifecycle hook.
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
export class AppComponent implements OnInit, OnDestroy {
private intervalId: any
private chillerDataSubscription: Subscription;
constructor() { }
ngOnInit() {
this.getRealTimeData();
}
getRealTimeData() {
this.getChillerApiData()
clearInterval(this.intervalId);
this.intervalId = setInterval(() => {
this.getChillerApiData();
}, 1000);
}
getChillerApiData() {
if (this.chillerDataSubscription) {
this.chillerDataSubscription.unsubscribe();
}
this.chillerDataSubscription = this.api.getFirstChillerData()
.subscribe((first_data:any) => {
this.first_api_data = first_data;
console.log(this.first_api_data)
this.putPrimaryPumpData();
});
}
ngOnDestroy() {
if (this.intervalId) {
clearInterval(this.intervalId);
}
if (this.chillerDataSubscription) {
this.chillerDataSubscription.unsubscribe();
}
}
}
See here for more details on lifecycle hooks.
I assume you are making a HTTP request inside your api service. In that case, notice the chillerDataSubscription
inside the getChillerApiData() function. It makes sure any outstanding requests are unsubscribed before making a new request. It prevents accumulation of too many requests.
Upvotes: 1
Reputation: 13515
You can clear up your component in ngOnDestroy
. This function is called by Angular when the component removed from the DOM.
You could clear the interval in ngOnDestroy
, but in your case you're probably better off performing the interval in RxJS, which your existing call can be part of.
// other imports here
import { interval } from 'rxjs';
import { takeUntil, switchMap } from 'rxjs/operators';
// @Component decorator here
export class MyComponent implements OnInit, OnDestroy {
// TODO: add constructor
private destroyed: Subject<void> = new Subject<void>();
ngOnInit() {
// create an rxjs interval every 1000ms
// or you could use timer(0, 1000) to start immediately
interval(1000).pipe(
// stop the interval whenever this.destroyed is called
takeUntil(this.destroyed),
// now make the api request
switchMap(() => this.api.getFirstChillerData())
).subscribe(data => {
this.first_api_data = data;
this.putPrimaryPumpData();
});
}
ngOnDestroy() {
// called when the component is removed from the DOM.
// cancel the interval and tidy up
this.destroyed.next();
this.destroyed.complete();
}
}
Upvotes: 1
Reputation: 1957
Exactly for cases like this angular provides the OnDestroy life cycle event. You can hook to this event the clear the interval.
like this:
intervalId : any
ngOnDestory() {
clearInterval(this.intervalId);
}
Upvotes: 1
Reputation: 3740
First of all there are so many things wrong here.
You call an subscribition and it's not unsubscribed. You want to unsubscribe the subscribition and you want to clear the interval. If the subscribition is not cleared it will keep getting info and keep repeating it. So putPrimaryPumpData will be called everytime the subscription is fired. Which can conclude in multiple running at the same time.
Do something like:
let sub = this.api.getFirstChillerData()
.subscribe((first_data:any) => {
sub.unsubscribe();
this.first_api_data = first_data;
console.log(this.first_api_data)
this.putPrimaryPumpData();
});
Now this will not create like 100 of 1000 of loops. Second you can use ngOnDestroy like:
ngOnDestroy() {
clearInterval(this.intervalId);
}
Upvotes: 1