Reputation: 473
Say I have some code like this
function Chart(start, end, controller, method, chart)
{
console.log('Chart constructor called');
this.start = start;
this.end = end;
this.controller = controller;
this.method = method;
this.chart = chart;
this.options = {};
}
Chart.prototype.update = function()
{
console.log('update ' + new Date().getTime());
$.getJSON('index.php', {
controller: this.controller,
method: this.method,
START: this.start,
END: this.end },
function(json) { this.draw(json); }); //<-- Problem right here!
}
Chart.prototype.draw = function(json)
{
//lots of code here
}
I'm getting the error Uncaught TypeError: Object #<an Object> has no method 'draw'
. Now, I'm the first to admit that I'm pretty new to Javascript. Am I supposed to call member functions in another way? Or am I supposed to do something different altogether?
edit: Here is how I'm creating my object:
chartObj = new Chart(start, end, 'OBF.RootCauses', 'ajaxRootCauses', chart);
Upvotes: 6
Views: 9495
Reputation: 40543
The problem here is that this
is changed because you are defining a new function - so this
refers to the function you are in.
There are other ways how to get around this, but the simplest way would be to save this
to a variable and call the function on that variable, something like this:
Chart.prototype.update = function()
{
console.log('update ' + new Date().getTime());
var self = this;
$.getJSON('index.php', {
controller: this.controller,
method: this.method,
START: this.start,
END: this.end },
function(json) { self.draw(json); });
}
See Chris's answer for a different approach for solving the same problem.
Upvotes: 6
Reputation: 868
Since you're already using jQuery, you can change this line
function( json ) { this.draw( json ); });
to this:
$.proxy( this.draw, this ) );
That will preserve the context where the function was called (i.e., the this variable).
Upvotes: 3