setInterval loop in ts.file giving me headache

I have a “tabata” timer. So far it counts down through a get ready phase, then a work phase and finally a rest phase. After the rest phase, I would like to re-loop through the work and rest phases several times.

However, at the end of the rest phase, the call to the work phase function does not work.

I get the following errors in the console.log when using the code below…

ERROR TypeError: Unable to set property ‘intervalOne’ of undefined or null reference

ERROR TypeError: Unable to get property ‘restTime’ of undefined or null reference

I am using the setInterval the same way so I don’t understand why this time it won’t work.

Why isn’t my code looping through?

I’ve put the seperate funtions in different places throughout the code, I taken away the setIntervals to get rid of the error, but of course that stops the counter counting down! I’m at a loss.

repeat(event) {
   this.intervalOne = setInterval(() => this.begin(this.countdown, this.tabata), 1000)
  }

  begin(myCountdown, myTabata) {
    let first = document.querySelector('#counter');
    this.set = this.set;
    if (this.set == 1) {
      this.countdown = myCountdown - 1;
      this.countdown > 0
      if (this.countdown < 10) {
        this.countdown = "0" + this.countdown;
      }
      first.innerHTML = this.countdown;
      if (this.countdown == 0) {
        clearInterval(this.intervalOne);
        this.intervalTwo = setInterval(() => work(), 1000)
        first.classList.remove('orange');
      }
      let intervalTwo = this.intervalTwo;
      let secondCount: any = +myTabata.split(':')[1];

      function work() {
        if (secondCount < 10) {
          secondCount = "0" + secondCount;
        }
        secondCount = secondCount - 1;
        secondCount > 0;
        first.innerHTML = secondCount;
        if (secondCount == 0) {
          clearInterval(intervalTwo);
          first.classList.remove('green');
          first.classList.remove('orange');
          secondCount = +myTabata.split(':')[1];
          this.intervalOne = setInterval(() => rest(), 1000)
          console.log(secondCount);
        }
      }
      let interval = this.intervalOne;
      let myRest = this.restTime;
      function rest() {
        if (myRest < 10) {
          myRest = "0" + myRest;
        }
        myRest = myRest - 1;
        myRest > 0;
        first.innerHTML = myRest;
        if (myRest == 0) {
          clearInterval(interval);
          myRest = this.restTime;
          this.intervalTwo = setInterval(() => work(), 1000)
        }
      }
    }
  }

I would suggest refactoring things to remove all instances of the keyword function. They’re prone to losing execution context. Use arrow functions and closures everywhere instead.

Thanks for the input.

Finally i realised I’d used my setInterval variables more than once; cancelling then recalling the same setInterval within the same function, for example. Anyway, I got it fixed. Thanks.

Consider using observable version of interval from a service

Potentially cleaner and multipurpose

1 Like