0

I'm trying a more object oriented approach with javascript and have implemented a class with some methods through the use of class.prototype.

But I have a problem.

I tried to use a method from myclass as the success function of an ajax call. The issue is I can't use this withing that method when is called back by ajax. I.E:

MyClass.prototype.myMethod = function(data)
{
this.data = data; /* in here this is the window object */
}
var myClass = new MyClass();
$.ajax:
    success:myClass.myMethod;

Am I doing something wrong?

Edit: Full function to try

am not i am

method

    function MyClass()
{
    this.name="myclass";
};

MyClass.prototype.print = function()
{
    alert(this.name);
};

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:function(data){
            func(data);
        }
    });
};


var refreshGroups = function(groups)
{
    var myClass = new MyClass();
    myAjax(myClass,myClass.print);
    return;
}

Result: alert is empty

3
  • Do you mean: $.ajax({ success:myClass.myMethod; });? Commented Mar 22, 2012 at 17:50
  • 1
    Javascript isn't OO, so the abstraction breaks pretty quickly. The myMethod function doesn't know it's meant to only act on your class, it's just a method. You will need to wrap the call in an anonymous function that calls the method on your object. Replace myClass.myMethod with function(){myClass.myMethod();} Commented Mar 22, 2012 at 17:52
  • 1
    @david JavaScript is OO, it just lacks bound methods because it binds this in a weird way. Commented Mar 22, 2012 at 17:55

2 Answers 2

2

"The issue is I can't use this withing that method when is called back by ajax."

Use the context: property of the $.ajax call.

$.ajax({
    url:...,
    context: myClass,
    success: myClass.myMethod
});

or use $.proxy...

$.ajax({
    url:...,
    success: $.proxy(myClass, 'myMethod')
});

Given the updated code, you'd need to change func(data) to be called from the calling context that you set using context:, so you do this.func(data)...

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:function(data){
            this.func(data);
        }
    });
};

...but since you're not doing anything in that anonymous function other than calling the function you passed, and passing on the argument, you could just do complete:func...

var myAjax = function(context_,func)
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        context:context_,
        complete:func
    });
};

...and the calling context of func will be set to the object you passed, and the data argument will still be passed to the function.


Of course, this really isn't an issue the way your code works, because you already have a closed reference to your context, so you could just as well skip passing the func, and just get it right from your object...

var myAjax = function(context_) // <-- no function argument needed
{
    $.ajax({
        url:"www.google.com",
        type: "GET",
        complete:function(data){
            context_.print(data);
        }
    });
};

var refreshGroups = function(groups)
{
    var myClass = new MyClass();
    myAjax(myClass); // <--just pass the object
    return;
}
Sign up to request clarification or add additional context in comments.

4 Comments

Dang it I need to write this on the back of my hand or something :-)
@doubter: I would need to see more code. What you've provided looks like a small fragment of the actual. Post more code and I may be able to help.
@amnotiam updated if you could take a look it would be great :)
@doubter: You would need this... complete:function(data){ this.func(data); }, or even better, just this... complete:func. I'll update my answer.
0

Methods in JavaScript aren't really bound in any deep way to object properties; they're just values. When you reference the function like that, the fact that this was involved when you set up the ajax call is completely lost.

There's a new-ish API to help:

success: this.myMethod.bind(this) // or myClass.myMethod.bind(myClass) ...

That .bind() method (from the Function prototype in newer browsers) returns another function that will call your method ensuring that this is correctly set up on that call.

There's a polyfill version of "bind" available at the MDN website (and there are others too). You can, alternatively, do the same thing explicitly:

var obj = this;
$.ajax({
  // ...
  success: function() { obj.myMethod(); },
  // ...
});

That "obj" variable is necessary to hold the outer-context value of this.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.