Chris Carr
Chris Carr

Reputation: 105

Countdown Timer not Stopping with clearInterval()

I'm having a problem get this countdown timer to stop at zero so the time won't show as a negative value. The console.log is getting called and works fine but for some reason the clearInterval() is not. This is driving me crazy and I'm close to quitting.

const timerContainer = document.getElementById('timerContainer');   

const THREEMINUTES = 60 * 0.1;//5 seconds for testing
	
startTimer(THREEMINUTES, timerContainer);

function startTimer(duration, display) {

		let start = Date.now();
		let diff, min, sec;

		let timer = () => {
			diff = duration - (((Date.now() - start) /        1000) | 0);
			//use bitwise to truncate the float
			min = (diff / 60) | 0;
			sec = (diff % 60) | 0;

			min = min < 10 ? '0' + min : min;
			sec = sec < 10 ? '0' + sec : sec;

			display.textContent = min + ':' + sec;

			if (diff <= 0) {
				stopTimer();
				submit.disabled = 'true'; 
			};

		};

		//call timer immediately otherwise we wait a      full second
		timer();
		setInterval(timer, 1000);

		function stopTimer() {
			clearInterval(timer);
    	console.log("time's up", diff);
    };
}
<div id="timerContainer"></div>

Upvotes: 0

Views: 1583

Answers (3)

Shahabaz
Shahabaz

Reputation: 665

The code is fixed make sure you fix your submit button code. You should first assign the value of setInterval to a variable. That variable is used while calling clearInterval which infact clears the interval.

const timerContainer = document.getElementById('timerContainer');   

const THREEMINUTES = 60 * 0.1;//5 seconds for testing

startTimer(THREEMINUTES, timerContainer);
var timer = null;
function startTimer(duration, display) {

        let start = Date.now();
        let diff, min, sec;

        let timer = () => {
            diff = duration - (((Date.now() - start) /        1000) | 0);
            //use bitwise to truncate the float
            min = (diff / 60) | 0;
            sec = (diff % 60) | 0;

            min = min < 10 ? '0' + min : min;
            sec = sec < 10 ? '0' + sec : sec;

            display.textContent = min + ':' + sec;

            if (diff <= 0) {
                stopTimer();
                submit.disabled = 'true'; 
            };

        };

        //call timer immediately otherwise we wait a      full second
        timer();
        timer = setInterval(timer, 1000);

        function stopTimer() {
            clearInterval(timer);
        console.log("time's up", diff);
    };
}

Upvotes: 0

Scott Marcus
Scott Marcus

Reputation: 65808

Don't pass the function that you want stopped to clearInterval().

Pass a reference to the timer that you started, so you need to make sure that when you start a timer, you capture a reference to the ID that will be returned from it.

// Function that the timer will invoke
function callback(){
    . . .
}

// Set up and initiate a timer and capture a reference to its unique ID
var timerID  = setInterval(callback, 1000);

// When needed, cancel the timer by passing the reference to it
clearInterval(timerID);

Upvotes: 2

Get Off My Lawn
Get Off My Lawn

Reputation: 36299

You are not saving the result of setInterval(timer, 1000);

you should use this:

let timerId;
timer();
timerId = setInterval(timer, 1000);

function stopTimer() {
    clearInterval(timerId);
    console.log("time's up", diff)
};

As you might see, the result of setInterval is a number (object in node), and all you then need to do is pass that value to clearInterval thus we save the value in the variable timerId for reference.

Upvotes: 3

Related Questions