Search code examples
angulartypescriptionic-frameworkweb-applications

How can I do a timer with Ionic?


I'm trying to do a sort of timer in my Ionic application, It should start when I load the page and it should add a value every second to a variable previously initialized to 0. I wrote this but it doesn't work:

  ngOnInit() {
 this.counter();
}


counter(){
  while(this.value!=1){
    timer(1000).subscribe(x => {this.value=this.value+0.075 })
  }
}

timer is a method imported from 'rxjs'.

The piece of HTML that must change during the time is:

<ion-progress-bar value={{value}} buffer={{buffer}}></ion-progress-bar>

And the variables are define here:

    private value_: number=0;
    private buffer_: number=this.value;

Finally I would like to say that I have already created the set and get methods.


Solution

    1. You don't actually need the subscription in the controller. You could use async pipe in template.
    2. You could start the timer immediately with initial delay set to zero: timer(0, 1000).
    3. Instead of while you could use takeWhile operator to complete the observable.

    Controller

    import { timer, Subject } from 'rxjs';
    import { map, takeUntil, takeWhile } from 'rxjs/operators';
    
    private stop$ = new Subject<any>();
    
    private value_: number = 0;
    private buffer_: number = this.value;
    
    timer$ = timer(0, 1000).pipe(
      takeUntil(this.stop$),               // stop when `stop$` emits
      takeWhile(_ => this.value_ < 1),     // are you sure `this.value_ == 1` is right?
      finalize(() => this.someMethod()),   // run this method when observable completes
      map(_ => {
        this.value_ = this.value_ + 0.075;
        return this.value_;
      }
    );
    

    Template

    // is buffer always set to zero?
    <ion-progress-bar [value]="timer$ | async" [buffer]="buffer"></ion-progress-bar>
    

    Update

    1. Use finalize operator to do something when the observable completes.
    2. Use takeUntil operator to stop the observable stream anytime. In this case I've used a RxJS Subject called stop$. When you wish to stop the stream, push to it like this.stop$.next().
    3. If you wish to run finalize only using takeWhile, then move the takeUntil operator below finalize. The someMethod() won't be triggered when you explicitly stop the stream.