CoolGravatar
CoolGravatar

Reputation: 5478

Javascript function scope

I'm trying to call an instance method a() from within a jQuery ajax call. But when I do so, it says that the method is not defined. I think it's because a() is not within the scope of $. But I thought it would be part of the scope chain. How can a() be within scope?

function Z() {
    this.x = 0
    this.a = function() {
      return this.x;   
    }
    this.b = function() {
        $.ajax({
            ...
            success: function(data, textStatus, xhr) {
                this.a(); //a() is not defined
            },
            ...
        }); 
    }  
}

z = new Z();
z.b();

Upvotes: 2

Views: 156

Answers (7)

Sinetheta
Sinetheta

Reputation: 9449

No "that" trick, change the context of the ajax callbacks

            context: this,
            success: function(data, textStatus, xhr) {
                this.a(); //a() is not defined

Upvotes: 2

Matt Ball
Matt Ball

Reputation: 360026

The other solutions will almost certainly work, but there's an even slicker, more idiomatic, way to do this with jQuery: use the context option with $.ajax():

context

This object will be made the context of all Ajax-related callbacks. By default, the context is an object that represents the ajax settings used in the call ($.ajaxSettings merged with the settings passed to $.ajax).


$.ajax({
    ...
    context: this,
    success: function(data, textStatus, xhr) {
        this.a(); //a() is now defined :)
    },
    ...
}); 

Upvotes: 2

Paul
Paul

Reputation: 141927

this is the jQuery Ajax object when you call this.a(). You need to do something like this:

function Z() {
    this.x = 0
    this.a = function() {
      return this.x;   
    }
    this.b = function() {
        var that = this;
        $.ajax({
            ...
            success: function(data, textStatus, xhr) {
                that.a(); //a() is not defined
            },
            ...
        }); 
    }  
}

z = new Z();
z.b();

Upvotes: 0

simon xu
simon xu

Reputation: 982

you can not use 'this' in the callback function.

function Z() {
var that=this;
this.x = 0
this.a = function() {
  return this.x;   
}
this.b = function() {
    $.ajax({
        ...
        success: function(data, textStatus, xhr) {
            that.a(); //a() is not defined
        },
        ...
    }); 
}  }

Upvotes: 1

stewe
stewe

Reputation: 42654

Try this:

function Z() {
    var that=this;
    this.x = 0
    this.a = function() {
      return that.x;   
    }
    this.b = function() {
        $.ajax({
            ...
            success: function(data, textStatus, xhr) {
                that.a(); //a() is not defined
            },
            ...
        }); 
    }  
}

z = new Z();
z.b();

Upvotes: 1

Delan Azabani
Delan Azabani

Reputation: 81482

Most people will suggest a trick like var that = this;, but I prefer using function binding to achieve the same end more elegantly and clearly.

Create a local function a, which is this.a bound to this:

function Z() {
    this.x = 0
    this.a = function() {
      return this.x;   
    }
    this.b = function() {
        var a = this.a.bind(this);
        $.ajax({
            ...
            success: function(data, textStatus, xhr) {
                a();
            },
            ...
        }); 
    }  
}

z = new Z();
z.b();

Upvotes: 3

titus
titus

Reputation: 5784

var that=this; use that.a. The this is not available from inner function/object, you have to use that=this trick.

Upvotes: 0

Related Questions