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);
}
Community
  • 1
  • 1
PLui
  • 765
  • 1
  • 10
  • 27
  • Maybe `this.getGroups` should be `anotherObject.getGroups`? – Waleed Khan Feb 28 '13 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? – Bergi Feb 28 '13 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);`? – Ian Feb 28 '13 at 14:37
  • 1
    I don't see any recursion, btw. – Bergi Feb 28 '13 at 14:39
  • @beri 'that.getSubGroups(group.id);' is recursive – David Barker Feb 28 '13 at 14:39
  • @Bergi I thought the same and used `that` at first but I was getting `Uncaught TypeError: Object # has no method 'callback'`. As for recursion, I'm calling `that.getSubGroups(group.id)`. – PLui Feb 28 '13 at 14:42
  • could you show the body of getGroup? – Sebas Feb 28 '13 at 14:44
  • @Sebas I have included the getGroups function in the question. – PLui Feb 28 '13 at 14:57

2 Answers2

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
Nikita Tkachenko
  • 2,116
  • 1
  • 16
  • 23
  • 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 Feb 28 '13 at 14:53
  • @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); }` – Nikita Tkachenko Feb 28 '13 at 14:55
  • 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);` – Nikita Tkachenko Feb 28 '13 at 15:08
  • 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? – PLui Feb 28 '13 at 21:10
  • 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! – PLui Feb 28 '13 at 21:28
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;
Sebas
  • 21,192
  • 9
  • 55
  • 109
Augustin Riedinger
  • 20,909
  • 29
  • 133
  • 206