0

I have a javascript Object called Company, which may be instantiated multiple times.

I want each Company to handle its own communication with the server, so that its ajax calls will be contained within the class.

So far I have:

Company = new Object();
Company.SendData = function(){
        $.ajax({
            type: "POST",
            url: "<some url>",
            data: <some data>,
            dataType: "json",
            success: this.ReceiveData,
            error: ErrorFunc
        });
}
Company.ReceiveData = function(data){
    alert("Received some data");
}

The Ajax works fine, and the server correctly receives the data and returns the response, but the call back function does not trigger.

My guess would be because it no longer has any frame of reference to what "this" is.

Is there a way that I can keep the functions attached to an individual instance of the class?

Sean Forman
  • 400
  • 4
  • 16
  • 2
    Check out the documentation on the `context` setting for `$.ajax`. http://api.jquery.com/jquery.ajax/#jQuery-ajax-settings – marekful Dec 12 '14 at 00:37
  • Related: [How to access the correct `this` / context inside a callback?](http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – Felix Kling Dec 12 '14 at 01:23

2 Answers2

1

Try this:

Company.SendData = function(){
 var self = this;
        $.ajax({
            type: "POST",
            url: "<some url>",
            data: <some data>,
            dataType: "json",
            success: function(res) {self.ReceiveData(res);},
            error: ErrorFunc
        });
}

This SO post might help to understand.

Update

Fixed the example by encapsulating the function.

Community
  • 1
  • 1
orange
  • 7,755
  • 14
  • 75
  • 139
  • 1
    Exactly what I would have suggested. – rfornal Dec 12 '14 at 00:35
  • This doesn't actually work. `self.ReceiveData` is the exact same value as `this.ReceiveData` at the time the argument is passed to `$.ajax()`. – jfriend00 Dec 12 '14 at 00:50
  • I am from C# background and I hate this keyword in JS. – Ahuman Dec 12 '14 at 00:59
  • @MrGenius - once you understand the 5 rules for how `this` is set, it is not hard, but it is mysterious until you understand those 5 rules. – jfriend00 Dec 12 '14 at 03:04
  • It's amazing that there are actually two upvotes for an answer that is completely wrong and does not work. There are more upvotes for this answer than for the other answer that offers three correct options that all work. Passing `self.receiveData` instead of `this.recieveData` doesn't do anything as `self` and `this` have the exact same value at the time the argument is passed to `$.ajax()`. What you need is a method of fixing the value of `this` when the callback is actually called which this does not do. – jfriend00 Dec 12 '14 at 03:05
1

There are several different choices for how to solve this issue. The crux of the problem is that you need to get the value of this set properly when your callback is called as it won't be correct by default.

In modern browsers, you can use the broadly useful .bind():

Company = new Object();
Company.SendData = function(){
        $.ajax({
            type: "POST",
            url: "<some url>",
            data: <some data>,
            dataType: "json",
            success: this.ReceiveData.bind(this),
            error: ErrorFunc
        });
}
Company.ReceiveData = function(data){
    alert("Received some data");
}

Or, you can instruct jQuery to do the work for you with the context option to $.ajax():

Company = new Object();
Company.SendData = function(){
        $.ajax({
            type: "POST",
            url: "<some url>",
            data: <some data>,
            dataType: "json",
            context: this,
            success: this.ReceiveData,
            error: ErrorFunc
        });
}
Company.ReceiveData = function(data){
    alert("Received some data");
}

Or you can create your own stub function using a saved value of this (this is my least favorite option):

Company = new Object();
Company.SendData = function(){
        var self = this;
        $.ajax({
            type: "POST",
            url: "<some url>",
            data: <some data>,
            dataType: "json",
            success: function(result) {return self.ReceiveData(result);},
            error: ErrorFunc
        });
}
Company.ReceiveData = function(data){
    alert("Received some data");
}
jfriend00
  • 683,504
  • 96
  • 985
  • 979