javascriptwebsockettimerclient-serverclearinterval

Javascript countdown timer, clearInterval not working


I have this countdown timer script:

/** WebSocket Setup */
//var ws = new WebSocket("CONFIG.WEBSOCKET_CONNECTION_PATH");

// jt localhost testing

var time = .25 * 60; // change first number for minutes to countdown
var constantTime = time;
var refreshIntervalId;
var start = false;
var countdown = document.getElementById("countdown");

function connect() {

    const ws = new WebSocket("ws:localhost:8000");

    ws.onopen = function (event) {
        sendGeneralMessage('history_timer_1', 'new_client');
    };

    ws.onmessage = function (event) {
        // parse into json, otherwise stop processing
        try {
            // clearInterval(refreshIntervalId);
            var payload = JSON.parse(event.data);
            console.log("RECEIVED: " + event.data);

            // continue processing if "event" field exists, stop processing otherwise
            if (payload.hasOwnProperty("event")) {
                console.log("has event field");
                // start clock is value is start, stop clock if value is stop, stop otherwise
                if (payload.event == "start" || payload.event == "stop") {
                    if (time != 0)
                        time = constantTime;

                    start = payload.event == "start";
                    console.log("start: " + start);

                    updateCountdown();
                }
                else {
                    console.log("value is not start or stop");
                    clearInterval(refreshIntervalId);
                    countdown.innerHTML = "00:00";
                }
            }
            else {
                console.log("has no event field");
                clearInterval(refreshIntervalId);
                countdown.innerHTML = "00:00";

            }
        } catch(e) {
            console.log("RECEIVED: " + event.data);
        }

    };

    ws.onclose = function(event) {
        console.log("CONNECTION CLOSED");

        setTimeout(function() {
            connect();
        }, 1000);
    };

    ws.onerror = function(event) {
        console.log("ERROR");
    };
}

connect();

function sendGeneralMessage(clientID, event) {
    var message = {client_id:clientID, event: event};
    // console.log(JSON.stringify(message))
    ws.send(JSON.stringify(message));
}

function updateCountdown() {
    if (!start)
        time = 0;

    // clearInterval(refreshIntervalId);

    refreshIntervalId = setInterval(function() {
        let minutes = Math.floor(time / 60);
        let seconds = time % 60;
        
        minutes = minutes < 10 ? '0' + minutes : minutes; //turns single digit minutes to double
        seconds = seconds < 10 ? '0' + seconds : seconds; //turns dingle digit seconds to double

        countdown.innerHTML = `${minutes}:${seconds}`;
        time--;
        if (time < 0) { //stop the setInterval to avoid negative time
            clearInterval(refreshIntervalId);
        }
    }, 1000);
}

When the "value is not start or stop" or "has no "event" field", I want the timer to stop counting down and show 00:00.

Right now, when the timer is counting down and one of those two events mentioned above happen, the timer show 00:00 for a split second and proceeds to count down from where it left off before the 00:00.

What can I do, so that the clock will stop counting down and show 00:00? clearInterval isn't working, am I using it wrong?

Edit: This is what I have on my server side to test it

ws.on("message", (message) => {
        console.log("received %s", message);
        setTimeout(function () {
                var msg = JSON.stringify({event:"start"});
                ws.send(msg);
                console.log("sent %s", msg);
        }, 3000);
        setTimeout(function () {
            var msg = JSON.stringify("hello");
            ws.send(msg);
            console.log("sent %s", msg);
        }, 8000);
});

When "hello" is sent, that is when it flashes 00:00 and then continues to count down from the start event before that.


Solution

  • document.addEventListener('DOMContentLoaded', function () {
        let time = 15; // in seconds
        let refreshIntervalId = undefined;
        let countdown = document.getElementById("countdown");
        let ws = undefined;
    
        function connect () {
    
            ws = new WebSocket("wss://localhost");
            ws.onopen = (event) => {
                sendGeneralMessage('history_timer_1', 'new_client');
            };
    
            ws.onmessage = (event) => {
                try {
                    let payload = JSON.parse(event.data);
                    console.log("RECEIVED: " + event.data);
    
                    if (payload.hasOwnProperty("event")) {
                        if (payload.event == "start") {
                            startCountdown();
                        } else if (payload.event == "stop") {
                            stopCountdown();
                        } else {
                            stopCountdown();
                        }
                    } else {
                        stopCountdown();
                    }
                } catch (e) {
                    console.log(e);
                }
    
            };
    
            ws.onclose = function (event) {
                console.log("CONNECTION CLOSED");
    
                setTimeout(function () {
                    connect();
                }, 1000);
            };
    
            ws.onerror = function (event) {
                console.log("ERROR", event);
            };
        }
    
        connect();
    
        function sendGeneralMessage (clientID, event) {
            var message = { client_id: clientID, event: event };
            ws.send(JSON.stringify(message));
        }
    
        function stopCountdown () {
            clearInterval(refreshIntervalId);
            countdown.textContent = "00:00";
        }
    
        function startCountdown () {
            time = 15;
            stopCountdown();
            refreshIntervalId = setInterval(function () {
                let minutes = Math.floor(time / 60);
                let seconds = time % 60;
    
                minutes = minutes < 10 ? '0' + minutes : minutes; //turns single digit minutes to double
                seconds = seconds < 10 ? '0' + seconds : seconds; //turns dingle digit seconds to double
                countdown.textContent = `${minutes}:${seconds}`;
                time--;
                if (time < 0) stopCountdown();
            }, 1000);
        }
    });