Home > Net >  Trouble with setInterval() and clearInterval() while creating a pomodoro timer
Trouble with setInterval() and clearInterval() while creating a pomodoro timer

Time:04-30

I've been learning javascript for the last few months, so I am a rookie. Longtime reader, first time poster. The full code for what I'm working on is available here in this codepen

https://codepen.io/dconnenc/pen/yLpwrQO?editors=1011

I'm hitting a pretty bad wall.

My current problem is keeping my clock maintaining proper mm:ss format, and getting it to tick down to 00:00.

min = min < 10 ? "0"   min : min;
sec = sec < 10 ? "0"   sec : sec;

I had been using the above, but it became too fragile inside of the interval function and begin adding 0s at the start at every interval. I have a fix so that it stops adding zeroes, but now it only ticks down to 0:00, and never reaches 00:00.

sessionTime = sessionTime < 10 && !sessionTime.toString().startsWith("0") ? "0"   sessionTime : sessionTime;
sec = sec < 10 && !sessionTime.toString().startsWith("0") ? "0"   sec : sec;

I've got stop for the day, and take a break, but a larger snippet of the code is below, and of course the link to the full codepen is above.

function timer() {
    //ticks down timer
    if(sec > 0){
      sec--;
    } else if (sec == 0 && sessionTime == 0) {
      console.log("check");
      document.getElementById('time-left').textContent = breakTime   ":"   sec;
    } else if (sec == 0) {
      sessionTime--;
      sec = 59;
    } 
  
    //mm:ss format (started running into an error with the interval returning extra 0s)
    sessionTime = sessionTime < 10 && !sessionTime.toString().startsWith("0") ? "0"   sessionTime : sessionTime;
    sec = sec < 10 && !sessionTime.toString().startsWith("0") ? "0"   sec : sec;
    
    //updates display
    document.getElementById('time-left').textContent = sessionTime   ":"   sec; 
}

CodePudding user response:

Try this with the min then with the seconds

if(sessionTime.toString().length === 1){
  if(sessionTime === 0){
     sessionTime = sessionTime;
    }else{
      sessionTime = "0" sessionTime;
   }
 
}

CodePudding user response:

This implements the expected behavior of your timer (Using a 500ms interval and 3 second "minutes") using a somewhat minimized example. Session Time is hardcoded to 3 minutes.

Mixing strings and integers in JavaScript can easily lead to coding issues like the ones you have experienced, especially when trying to use the operator on mixed strings and integers. Best to avoid that in your control variables and lead with an obvious string when you're setting displays.

let oneSecond = 500;
let oneMinute = 3;

let sessionTime = 3;

var secondsRemaining;
var intervalId;

function reset() {
    console.log('check')
    clearInterval(intervalId);
    intervalId = 0
}

function start() {
    secondsRemaining = sessionTime * oneMinute;
    setTimeLeft()
    intervalId = setInterval(timer, oneSecond)
}

function timer() {
    if ( --secondsRemaining <= 0 ) {
       reset()
    }
    setTimeLeft()
}

function setTimeLeft() {
    document.getElementById('time-left').textContent = `${(''  ~~(secondsRemaining / oneMinute)).padStart(2, '0')}:${(''  secondsRemaining % oneMinute).padStart(2, '0')}`;
}

start()
<span id='time-left'></span>

This version handles multiple timers.

let oneSecond = 500;
let oneMinute = 3;

let sessionTime = 3;

function Timer(seconds, resetCallback, updateCallback, period) {
    this.s = seconds;
    this.p = period || oneSecond;
    this.callback = resetCallback || Function.prototype;
    this.update = updateCallback || Function.prototype;

    this.reset = function() {
      this.intervalId = clearInterval(this.intervalId)
      this.callback()
    }
    this.start = function() { this.update(this.s); this.intervalId = setInterval(this.timer.bind(this), [ this.p ]) }
    this.timer = function() { if (--this.s <= 0) this.reset(); this.update(this.s) }
}

function setTimeLeft(sec, id) {
  document.getElementById(id || 'time-left').textContent = `${(''  ~~(sec / oneMinute)).padStart(2, '0')}:${(''  sec % oneMinute).padStart(2, '0')}`;
}

document.addEventListener("DOMContentLoaded", function() {
  new Timer(sessionTime * oneMinute, () => console.log('check 1000ms'), setTimeLeft, 1000).start()
  new Timer(6 * oneMinute, () => console.log('check 500ms'), (s) => { setTimeLeft(s, 'time-left2')}, 500).start()
  new Timer(15 * oneMinute, () => console.log('check 300ms'), (s) => { setTimeLeft(s, 'time-left3')}, 200).start()
})
<span id='time-left'></span><br />
<span id='time-left2'></span><br />
<span id='time-left3'></span>

  • Related