0

I am well aware this is not very Angular friendly, in fact I'd like to know from you a better fix to make it more "Angular-y" if possible, thank you.

export class TimerComponent implements OnInit {
  min = 0;
  sec = 0;
  minutesLabel: any = document.getElementById('minutes'); 
  secondsLabel: any = document.getElementById('seconds');

  startTimer() {
    const interval = setInterval(this.setTime, 1000); 
    return interval;
  }

  setTime() {
    ++this.sec;
    var r: any = this.sec / 60;
    this.secondsLabel.innerHTML = this.pad(this.sec % 60);
    this.minutesLabel.innerHTML = this.pad(parseInt(r));
  }

  pad(val: any) {
    var valString = val + '';
    if (valString.length < 2) {
      return '0' + valString;
    } else {
      return valString;
    }
  }

  constructor() {}

  ngOnInit() {}
}
tearex
  • 47
  • 7
  • 3
    Does this answer your question? [How to access the correct \`this\` inside a callback](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – jonrsharpe Oct 26 '21 at 13:34

2 Answers2

3

You have a few solutions here:

setInterval(this. setTime.bind(this), 1000); 

or:

setInterval(() => this.setTime(), 1000); 

The reason being that when you pass setTime into setTimeout, the this scope of your object instance isn't preserved.

Fabian Lauer
  • 8,891
  • 4
  • 26
  • 35
0

Here is a answer that also makes it as you said "Angular-y".

This makes use of rxjs timer which is similar to setTimeout but more configurable, form prod use you will need some way to unsubscribe on destroy.

I also simplified a lot here that was not needed, as well as added better type definitions.

import { Component, OnInit } from '@angular/core';
import { timer } from 'rxjs';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
  minutesLabel: string;
  secondsLabel: string;

  ngOnInit() {
    timer(0, 1000).subscribe((sec) => {
      this.secondsLabel = this._pad(sec % 60);
      this.minutesLabel = this._pad(Math.floor(sec / 60));
    });
  }

  private _pad(val: number) {
    var valString = val + '';
    if (valString.length < 2) {
      return `0${valString}`;
    } else {
      return valString;
    }
  }
}
DrakeAnglin
  • 718
  • 1
  • 4
  • 12