I\'m trying to create a Timer
that calls an API call
every 10 seconds, I\'m using setTimeOut
but the thing is that it becomes an infin
Use observable.timer
for your purpose in angular way.
export class CurrentRunsComponent implements OnInit, OnDestroy {
private timer;
ngOnInit() {
this.timer = Observable.timer(10000);
this.timer.subscribe((t) => this.onTimeOut());
}
onTimeOut() {
this.ApiCall().then(
success => {
if(success ['ok'] == 0){
this.navCtrl.push(myPage);
}
},
error => { console.log(error); });
}
ngOnDestroy(){
console.log("Destroy timer");
}
}
There is nothing wrong with setTiimeout, It’s just a bug in your codes. This is indeed an infinite loop(recursive function without a base condition) as you don't have any base condition there.
So, setTimeout will keep on calling onTimeOut() after every 1 second as it does not know where to stop. Just use a base condition to finish the recursion when you switch to other pages.
private flag: boolean;
ngOnInit() {
this.flag = true;
}
ngOnDestroy() {
this.flag = false;
}
onTimeOut() {
this.ApiCall().then(
success => {
if(success ['ok'] == 0){
this.navCtrl.push(myPage);
}
},
error => { console.log(error); });
}
setTimeout(() => {
if(this.flag){
this.onTimeOut();
}
}, 1000);
}
ngOnDestroy
method will set the flag as false and the last call of the recursive function won't go inside the if block and as there is nothing to be executed after that, It will return back (previous state of it) and will clear it up from the stack, This process will be repeated till the stack is cleared up(same thing would happen to previous version of it which is now on the top of the stack and thus will clear up the stack one by one recursively).
Better use observables
this.sub = Observable.interval(10000)
.subscribe((val) => { console.log('called'); });
to stop it use
this.sub.unsubscribe();
Make sure to import interval
with
import 'rxjs/add/observable/interval';
A better solution than setTimeout in an Angular app could be to use Observable. Observable have a method named timer that you can use this way (and there is a TimerObservable too but I never used it so I don't know if this is the same thing):
timer = Observable.timer(initialDelay, period);
timer.subscribe(tick => {
// Your API call, which will be performed every period
});
I encourage you to use RxJS and Observable for your requests too, instead of promises, it seams more the Angular way to do things to me, and RxJS is a really powerful library.
RxJS Observable doc
from RxJS 6+ you just use interval.
import { interval } from 'rxjs';
//in 10 seconds do something
interval(10000).subscribe(x => {
this.myFunctionThatDoesStuff();
});
you can use Subscription
with the interval.
import { interval, Subscription} from 'rxjs';
export class intervalDemo{
mySubscription: Subscription
constructor(){
this.mySubscription= interval(5000).subscribe((x =>{
this.doStuff();
}));
}
doStuff(){
//doing stuff with unsubscribe at end to only run once
this.failedRequestSub.unsubscribe();
}
}