javascriptsettimeoutsetintervalclearintervalcleartimeout

Repeated use of clearInterval and clearTimeout not working


I was passed this half built JS code at my work. The objective is to log an inactive users out or give them an option to stay logged into the system.

This may be an obvious error. I am trying to learn (and impress my work). But I am hitting my head against the wall here and do not see the problem. Sometimes an extra set of eyes sees something we can't. Right?

Steps: First a modal opens displaying a warning if no activity is detected. The modal starts a timer that when completed logs the user out of the system.

If the user clicks the "stay logged in" button that is in the modal, the process is reset.

If the user does not click the "stay logged in" button, they are logged out of the system.

Everything works. The first time. LOL!!

Problems: If the user keeps clicking to stay logged into the system there are issues: A) The count down time displayed in the modal flickers two different numbers. B) The count down clocks do not honor the correct duration until the function executes.

Why are the clearTimeout and clearInterval not working? What am I missing?

Here is a CodePen of my code (with HTML and CSS)

$(document).ready(function(){
    var warningTimeout = 9800;
    var timoutNow = 10000;
  console.log(`${warningTimeout} warningTimeout | ${timoutNow} timoutNow |`);


    var warningTimerID,timeoutTimerID, countDownFunction;

    function startTimer() {
        warningTimerID = window.setTimeout(warningInactive, warningTimeout);
    }



    function countDownToLogOut() {
        let countDownSeconds = timoutNow / 1000
        let timerVisualDisplay = $("#session-logout-time")
        function displayCountdown() {
            if (countDownSeconds === 0){ 
                IdleTimeout()
            }
            console.log(`${countDownSeconds}|countDownSeconds`);

            timerVisualDisplay.text(`${countDownSeconds--} seconds`)
        }

        countDownFunction = window.setInterval(displayCountdown
        ,1000)
    }

    function warningInactive() {
        window.clearTimeout(warningTimerID);
        $('#session-logout-modal').show();
        countDownToLogOut();
    }

    function resetTimer() {
        if($('#session-logout-modal').css('display') == 'none'){
            window.clearTimeout(timeoutTimerID);
            window.clearTimeout(warningTimerID);
        }
        startTimer();
    }

    // Logout the user.
    function IdleTimeout() {
        console.log("you are logged out")
    }

    function setupTimers () {
        document.addEventListener("mousemove", resetTimer, false);
        document.addEventListener("mousedown", resetTimer, false);
        document.addEventListener("keypress", resetTimer, false);
        document.addEventListener("touchmove", resetTimer, false);
        document.addEventListener("onscroll", resetTimer, false);
        startTimer();
    }

    $(document).on('click','#btnStayLoggedIn',function(){
        $('#session-logout-modal').hide();
        window.clearInterval(countDownFunction);
        $("#session-logout-time").text('calculating...')
        resetTimer();
    });

    setupTimers();

});

I have read and tried these three pages. And even if they did help me, I want to be a better developer to understand what was going wrong with this code. Some pages I read:

FirstArticle

SecondArticle

ThirdArticle

Thanks in advance!


Solution

  • Your issue here seems to be that you are not clearing the old timers before starting new ones. I'd suggest the follow just be safe:

    function startTimer() {
      // window.setTimeout returns an Id that can be used to start and stop a timer
      if (warningTimerID) {
        window.clearTimeout(warningInactive);
      }
      warningTimerID = window.setTimeout(warningInactive, warningTimeout);
    }
    
    

    and then for your countDownToLogOut() function, add this before calling the countDownFunction setInterval:

    if (countDownFunction){
      window.clearInterval(countDownFunction)
    }