Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve Var out of scope within setTimeout call

I am trying to call a setTimeout from within a setInterval callback:

function callback()
{
   //assign myVar
   var myVar = document.getElementById("givenID");
   //...
   //now wait 2 secs then call some code that uses myVAr
   setTimeout("myVar.innerHTML = 'TEST'", 2000);
}

setInterval("callback();", 10000);

setInterval works as expected but setTimeout call is failing. I guess the problem is related to the fact that I am referencing a variable (myVar) that's not in scope.

What's the best way to solve this?

like image 244
JohnIdol Avatar asked Oct 26 '08 01:10

JohnIdol


4 Answers

This is a perfect candidate for closures:

setInterval(
    function ()
    {
       var myVar = document.getElementById("givenID");
       setTimeout(
          function()
          {
              // myVar is available because the inner closure 
              // gets the outer closures scope
              myVar.innerHTML = "Junk";
          },2000);
    }, 10000);

Your problem is scope related, and this would work around that.

like image 60
FlySwat Avatar answered Nov 05 '22 01:11

FlySwat


I had a similar problem. The issue was that I was trying to call a method from within itself through a setTimeout(). Something like this, WHICH DIDN'T WORK FOR ME:

function myObject() {

   this.egoist = function() {
      setTimeout( 'this.egoist()', 200 );
   }

}

myObject001 = new myObject();
myObject001.egoist();

The following ALSO DIDN'T WORK:

... setTimeout( egoist, 200 );
... setTimeout( egoist(), 200 );
... setTimeout( this.egoist, 200 );
... setTimeout( this.egoist(), 200 );
... setTimeout( function() { this.egoist() }, 200 );

The solution was to use with() statement like so:

function myObject() {

   this.egoist = function() {
      with (this) { setTimeout( function() { egoist() }, 200 );}
   }

}

myObject001 = new myObject();
myObject001.egoist();

Of course, this is an endless cycle, but the point I'm making here is different.

Hope this helps :)

like image 32
svinec Avatar answered Nov 05 '22 00:11

svinec


As a matter of best-practice, try not to use strings as parameters to setTimeout and setInterval because that will invoke eval ... Using the following form might also make this problem easier to understand/debug:

setInterval(function () {
    // do stuff
    // ...
    // now wait 2 secs then call someFunction
    setTimeout(someFunction, 2000);
}, 10000);
like image 4
Andrew Hedges Avatar answered Nov 04 '22 23:11

Andrew Hedges


Run it in Firefox and check Tools | Error Console. if setTimeout fails it may tell you why there.

Also, try replacing "someFunction();" with "alert('hi')" (no semicolon) and see if that works. If so, the problem is narrowed down significantly.

like image 1
Michael Gundlach Avatar answered Nov 05 '22 01:11

Michael Gundlach