views:

59

answers:

3

hi guys, I'm having some trouble with JavaScript and the passing of a function as parameter of another function.

let's say we are inside a class and do something like that:

this.get('target').update(this.onSuccess, this.onFail);
  • 'target' is a JavaScript-object that has a method called update()
  • I'm calling this method and pass tow methods of the caller-class along as parameters

inside that update-method some stuff happens and when it's done that method should either call the onSuccess-method or the onFail-method. this looks something like:

update: function(onSuccess, onFail) {
  if(true) {
    onSuccess();
  } else {
    onFail();
  }
}

until now, everything works pretty fine! but inside those success/fail-methods, that are defined in the caller-class (the one that calls above update-method), I'm using a this-pointer:

onFail: function() {
  alert('Error: ' + this.get('target').error);  
}

that this-pointer causes some issues. it doesn't point to the class where the method initially was defined but to the 'target'-object.

what I need to do now is to update the this-pointer right before the onSuccess / onFail calls inside the 'target'-class to make the methods work again. but this doesn't work due to a 'invalid assignment left-hand side'-error.

what is the best practice for a scenario like that? any ideas? thx in advance!!!

cheers

+3  A: 

You have two options when calling update():

  • javascript function call()
  • javascript function apply()

the main difference being how you pass parameters to it. But they both allow scope/context injection.

Your code should look something like this:

this.get('target').update.call(this, this.onSuccess, this.onFail);
Robert Koritnik
+1  A: 

To redirect this, you need a bind() (or similar) method in the Function class, as found in almost all JavaScript libraries:

if(!Function.prototype.bind){
    Function.prototype.bind = function(scope) {
      var _function = this;

      return function() {
        return _function.apply(scope, arguments);
      }
    }
}

Now do something like this:

update: function(onSuccess, onFail) {
  if(true) {
    onSuccess.bind(this)();
  } else {
    onFail.bind(this)();
  }
}

The mechanism is explained here: Binding Scope in JavaScript

seanizer
+2  A: 

You can create a function that "binds" a function to a certain object (using a closure) and than pass these bound functions to the handler:

function bind(obj, fun) {
   return function() {
      return fun.apply(obj, arguments);
   };
};

update(bind(this, this.onSuccess), bind(this, this.onFail));
sth
thx, that solved my problem! I forgot to mention that I can't make any bigger changes inside the caller-class! so I only pass the 'this-pointer' along and to the binding-stuff inside the target-class. that works perfectly fine!!
NATOR