Search code examples
javascriptsetintervalcleartimeout

clearTimeout not working - Tried many variations


I have an issue with the clearTimeout function. Both conditions are working but The timeout refuses to clear...... any help is welcome. The time is 300 miliseconds = params.speed.

**NOTE: The method is totally functional and working. The only issue I am having is clearing the setTimeout. It creates a bug where new non-timeout toasters are having the old setTimeout apply.

Meaning if I click the non-time-out button within 3 seconds after clicking the timeout button, the old setTimeout is still applying to the next toaster.

        // Beginning of function - line below contains the options for the 
        // toaster method:
        // Invoke via - onclick(e, {text: 'This is an alert with a TIMER', 
        // timer:true, speed: 3500, color: 'dark'})

        toaster: function(e, params = {}) {

            // Set defaults for params.object options
            var setDefaults = function () {
                if (e == null) {
                    e = this.event;
                };
                if (params.speed == null) {
                    params.speed = 3500;
                };
                if (params.timer == null) {
                    params.timer = false;
                };
                if (params.color == null) {
                    params.color = 'light';
                };
                if (params.text == null) {
                    params.text = 'This is a default warning'
                };
            }();

          //Apply timer function
          timerOn(params.speed); // params.speed = 4500
          var timing; // Variable set outside of the timerOn() function

          function timerOn () {

                if (params.timer) {
                    timing = setTimeout(function(){
                        el[0].classList.remove('show-toaster');
                        console.log('happening');
                    }, params.speed);  
                } else {
                    clearTimeout(timing);
                    console.log('just cleared timing variable');
                } 

            } // timerOn ends

Solution

  • What we have here I believe is a problem of scope,.

    Let's say we have a function test, and when we call it with true we save the word hello into a var called x. If we then call said function again with false we want it to console.log the value of x, hopefully been the word hello.

    We could create function like this->

    function test(b) { var x; if (b) x = "hello"; else console.log(x); }
    test(true); 
    test(false);  //prints undefined
    

    Now the above based on what the OP has said, is kind of what he's doing with the toaster function. Problem is the above will end up printing undefined

    So how do we fix,. All we have to do is move the var x declaration so it covers the function test, this will then make the var x scope global to this instance of test. IOW: every time we call test we want it to see the same instance of x..

    So here is the fixed version.

    var x; function test(b) { if (b) x = "hello"; else console.log(x); }  
    test(true); 
    test(false);  //prints hello
    

    This as expected will print the word hello..

    Now if you think of the function test been the toaster function, and the var x been the timer var, you can see how the timer var will end up been undefined the next time you call toaster..