0

In relation to this question, I'm trying to add a callback to get the data back. So I tried this:

var subgroupIds = [];
var that = this;
this.getSubGroups = function (groupId,callback) {
    var anotherObject = this;
    this.getGroups("groupId="+groupId, function(groups) {
        if ($.isEmptyObject(groups)) {
            return;
        } else {
            $.each(groups, function(index,group) {
                subgroupIds.push(group.id);
                that.getSubGroups(group.id);
            });
            anotherObject.callback(group.id);
        }
     });
}

I thought I have a better understanding of closure after the previous question but I guess I don't...I'm getting the following error:

Uncaught TypeError: Object [object Window] has no method 'callback'

What am I doing wrong here?

Edit

Here's the content of getGroups:

this.getGroups = function(filter,callback,error_callback) {
    this.getJSON('/'+apiVersion+'/groups/',function(data){
        // run through the filter engine
        output = runFilter(data, filter);
        callback(output);
    },error_callback);
}
8
  • Maybe this.getGroups should be anotherObject.getGroups? Commented Feb 28, 2013 at 14:34
  • Why do you use anotherObject instead of that? And why do you callback to a property, don't you want to callback to the function argument? Commented Feb 28, 2013 at 14:37
  • What is this/that? When you are declaring this.getSubGroups, this refers to window, so you're not doing something right to get this to refer to the right thing. Then, anotherObject just refers to the same, window. Also, why are you trying to use anotherObject.callback(group.id)? Don't you just want callback(group.id);? Commented Feb 28, 2013 at 14:37
  • 1
    I don't see any recursion, btw. Commented Feb 28, 2013 at 14:39
  • @beri 'that.getSubGroups(group.id);' is recursive Commented Feb 28, 2013 at 14:39

2 Answers 2

1

It doesn't need to be anotherObject.callback(group.id);, what you need is callback(group.id);

It looks like you're confusing this with arguments object.

arguments holds all parameters that are passed into the function:

var aFunction = function () {
    for (var i = 0; i < arguments.length; i++) {
        console.log(arguments[i]);
    }
};

aFunction(1, 2, 3, 4); // 1, 2, 3, 4

While this basically refers to the "owner" of the function (which is, roughly speaking, whatever happens to be before the dot):

var aFunction = function () {
    console.log(this);
};

var object1 = { f: aFunction, name: "object1" };
var object2 = { f: aFunction, name: "object2" };

object1.f(); // Object { name="object1", f=function()}
object2.f(); // Object { name="object2", f=function()}
aFunction(); // Window
Sign up to request clarification or add additional context in comments.

5 Comments

I think I understand what you're saying. I thought I was getting the error due to callback is an argument of getSubGroups and getGroups has not visibility to callback since it's another level down. I tried changing anotherObject.callback(group.id); to callback(group.id); but I got this error: Uncaught TypeError: undefined is not a function
@PLui That is because of your recursive call to that.getSubGroups(group.id); - you do not provide the second parameter - the callback - which is why it is undefined. You either have to provide a callback each time you call the function, or introduce a check: if (callback) { callback(group.id); }
if you want the same callback to be invoked in every recursive call, you just have to pass it along: that.getSubGroups(group.id, callback);
ah that got me a lot closer. What I'm noticing now is if I have a group structure where I have a grandparent, parent and child, the recursive nature of this function will essentially call getSubGroups three times (for each level). This causes callback to be called twice. I really just want the last subgroupIds since that gives me the complete list of sub-groups. How do I get around that?
I think my logic is flawed. I shouldn't return an array. Instead, perhaps I should just use callback(group.id) as I find the subgroups. Thanks or the help Nikita!
0

The callback is a parameter, it is not bound to the context.

I think what you want is to call the callback with anotherObject as the this value, right ?

You can achieve that with :

$.proxy(callback, anotherObject)(group.id);

Or if you only want to execute the callback, and you want to use closure, you need to add :

this.callback = callback; //before
var anotherObject = this;

1 Comment

With that proxy thing you mean callback.call(anotherobject, group.id)?

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.