2

I am still new to Ionic and especially Angular. I want to update a textview with a number going from 10 to 0 and update each second.

In my class I got a property public timeLeft: string = 'Your timer'; which is bound to the html with <div>{{timeLeft}}</div>

I have tried using regular JavaScript setInterval() but it fails when I'm trying to update the property timeLeft using the keyword this because this is not in the same scope as the class when running the setInterval function.

I've read that I should use the Angular function $interval because it has access to the same scope or view, didn't quite understand that part fully.

I found some pieces of code saying I should make a controller and it should contain something along the lines of myApp.controller(function($scope, $interval) {...})

On the Ionic blog I found a post mentioning that some Angular 1 concepts as controllers and scope is out.

So my question is. How do I use Angular $interval to update a textview at an interval in Ionic? A full code example would be fantastic as I'm literally lost here.

  • cli-utils: 1.9.2
  • Ionic CLI: 3.9.2
  • Cordova CLI: 6.5.0
  • ionic app-scripts: 2.1.3
  • Ionic Framework: ionic-angular 3.6.0
Sampath
  • 63,341
  • 64
  • 307
  • 441
Kim
  • 1,158
  • 8
  • 18

1 Answers1

3

You can use Observable.timer here.Please try below code.

Creates an Observable that starts emitting after an initialDelay and emits ever increasing numbers after each period of time thereafter.

Its like interval, but you can specify when should the emissions start.

Here is the working Plunker

import {Component} from '@angular/core'
import {Observable} from 'rxjs/Observable'
import 'rxjs/add/observable/timer'
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/take'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h1>Countdown timer</h1>
      <h2>{{timeLeft | async}}</h2>
    </div>
  `,
})
export class MyApp {

  timeLeft;
  counter = 10;
  constructor() {

    this.timeLeft = Observable.timer(1000,1000)
      .take(this.counter)
      .map(() => --this.counter)

  }
}

Update:

html

 <h2>{{timeLeft}}</h2>

.ts

 Observable.timer(1000,1000)
      .take(this.counter)
      .map(() => --this.counter).subscribe(val => {
          //you can do transformation here
       }
Sampath
  • 63,341
  • 64
  • 307
  • 441
  • Thank you for your example, I'm using milliseconds and then counting down one second at a time and I need to keep track using pause/stop. My question is, instead of writing the number to the view could I get the number and then make the remaining milliseconds human readable like this `var date = new Date(timerLength - timerProgress); this.timeLeft = date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds()` – Kim Aug 23 '17 at 16:52
  • Yes, You can do that.You need to use `momentJs` for that.See this:https://stackoverflow.com/a/45796889/1077309 – Sampath Aug 23 '17 at 16:57
  • I see, but what I mean is that the Observable returns a number directly to the view, I'd like to work with that data before putting it to the view. timerLength is how long the timer is in milliseconds, timerProgress is how far I am in the timer. Then I could subtract the two to get the remaining time and from that make it human readable and put it to the view. – Kim Aug 23 '17 at 17:05
  • Please see the **Update** above. – Sampath Aug 23 '17 at 17:14