Reputation: 93
I started writing coffeescript last week, as I am programming a new Play20 site where coffeescript is the standard. I want to update a getData function in my class every 5 minutes, but the setInterval function does not bind to my class. Only the first time it calls getData, because the 'this' object is still reachable, as the setUpdateInterval() function is called from within the constructor.
But after the first call, the setInterval does not have any connection anymore with the Widget instance, and does not know what the this.getData() function is (and how to reach it).
Does someone know how to do it?
Here is my code:
class Widget
constructor: (@name) ->
this.setUpdateInterval()
getData: ->
console.log "get Data by Ajax"
setUpdateInterval: (widget) ->
setInterval( this.getData(), 3000000 )
Upvotes: 3
Views: 4009
Reputation: 53
This is handy in node as well. It's a varient of Tass's answer.
class Widget
constructor: (@options = {}) ->
@options.interval ?= 1000
@setInterval()
timer: ->
console.log 'do something'
setInterval: ->
cb = @timer.bind @
setInterval cb, @options.interval
w = new Widget()
Upvotes: 0
Reputation: 21740
Now here some Javascript magic is required. Reference
class Widget
constructor: (@name) ->
this.setUpdateInterval()
getData: ->
console.log "get Data by Ajax"
setUpdateInterval: (widget) ->
callback = @getData.bind(this)
setInterval( callback, 3000000 )
This will work in almost all browsers (guess which one not), so the function will have to be bound differently. Some coffeescript magic:
callback = => @getData
Upvotes: 7
Reputation: 120318
The problem is that you are executing the function, instead of passing a reference to it.
Now, it sounds like you need to also keep the scope of the instance. do
and =>
can help with that.
setUpdateInterval: (widget) ->
setInterval (do =>
@getData), 3000000
true
compiles to
Widget.prototype.setUpdateInterval = function(widget) {
var _this = this;
setInterval((function() {
return _this.getData;
})(), 3000000);
return true;
};
you will note the code executes a self invoking function, which return a function, that creates a closure around this
, locking it into the scope of the callback (as _this
)
Also note that you don't need to pass widget to the method (you aren't using it anywhere), and you would invoke this function in your constructor, to set up the interval. Whatever you do, you only want to call this method once. You could just put the contents of the function in your constructor.
Finally, since coffeescript returns the value of the last statement from all functions, I throw a true
in there, but that might no be necessary.
Upvotes: 3