GameDroids
GameDroids

Reputation: 5662

JQuery-UI Widget undefined when using interval

I want to create a Jquery UI widget that starts an interval on creation. The function called on each interval timeout is supposed to be overrideable and therefore placed in the options object.

I can start the interval from outside the widget, and I can call the overrideable function from outside the widget. But when the interval tries to call the overrideable function, it's undefined.

Here is my widget:

jQuery.widget("awesome.me", {
    options: {
        verbose:false,                        // just some setting
        onTimeOut: function(){                // this is the function that is called by the timeout and that should be overrideable 
            console.log("on timeOut called");
        }
    },
    _create: function(){
        console.log(this.options);            // logging the options object
    }, 
    _members: {                               // a private object to hold internal settings and stuff, for example the interval instance
        interval: null
    },
    start: function(){        
        this._members.interval = setInterval(this.doIt, 2000);
    },
    stop: function(){
        clearInterval(this._members.interval);
    },
    doIt: function(){
        console.log(this.options);            // here I would like to call my onTimeOut function, but the options are undefined, because THIS is undefined
    }
});

From the outside, in the script I do this to instantiate my widget and start the interval:

$(document).me();                              // I am not overriding the function for now
var widget = $(document).data("awesome-me");   // to facilitate access to my widget I grab the instance and put it in a normal variable
widget.start();                                // start() will set the interval

If I where to call widget.doIt(), the console would show something like this:

 Object {classes: Object, disabled: false, create: null, verbose: false}

But when I run the script, every two seconds this appears:

undefined

So from my understanding, when I call widget.start(), the interval will start calling this.doIt every 2 seconds, but inside the doIt function, when it tries to log the options object, it is gone. So my widget variable still has the correct instance of my widget and I can call every function I want. But when the interval times out, it holds some other widget instance where the function doIt exists, but this is undefined.

What I don't understand is: why? How I can fix this?

Upvotes: 2

Views: 196

Answers (1)

TheSharpieOne
TheSharpieOne

Reputation: 25726

The problem is with this._members.interval = setInterval(this.doIt, 2000);

When this.doIt is called, it is called with this being window, which in turn is really, window.options which is being accessed in doIt (do console.log(this) to see what it is inside of doIt when it is ran).

The fix is to bind or execute doIt passing this.

this._members.interval = setInterval(this.doIt.bind(this), 2000);

or

var self = this;
this._members.interval = setInterval(function(){self.doIt();}, 2000);

Upvotes: 2

Related Questions