You need to use the .call() or .apply() methods on the callback to specify the context which the method is called upon.
The callback method remote_submit does not know what this will be anymore and thus when it calls the callback methods they're executed like normal functions not on an object.
You can "Bind" your functions by wrapping them on the way out:
var self = this;
remote_submit(
identify,
function() { return self.success.apply(self, arguments); },
function() { return self.error.apply(self, arguments); }
);
This allows you to pass the context in the closure of the anonymous function and execute the callbacks with an exclusive this context.
It appears that in EMCAScript5+ you can use bind on the function to bind it for use in a callback:
remote_submit(identify, this.success.bind(), this.error.bind())
However from the MDN Documentation:
The bind function is a recent addition to ECMA-262, 5th edition; as such it may not be present in all browsers. You can partially work around this by inserting the following code at the beginning of your scripts, allowing use of much of the functionality of bind() in implementations that do not natively support it.
The shim/polyfill is here:
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}
Update:
To answer your additional question, let's first look at the call and apply documentation and break down how they work:
Fundamentally they work the same, the only difference is how they take their arguments:
myfunc.call(target, param1, param2, param3);
Will call myfunc(param1, param2, param3) with target as this.
var args = [param1, param2, param3];
myfunc.apply(target, args);
Will call myfunc(param1, param2, param3) with target as this.
Basically the difference is that .apply() takes an array of arguments, where the call function requires you to write in the arguments in the code.
Next, if we look at the example i gave you:
function() { return self.success.apply(self, arguments); }
This returns a function that will call your callback by passing all the arguments (arguments variable) that were passed into the anonymous function, onto the apply function. So:
var a = function() { return self.success.apply(self, arguments); };
a(1,2,3,4);
This will call self.success(1,2,3,4) with self as this. If you'd like to augment the arguments with something specific for example if you wanted a(1,2,3,4) to call self.success(self.test, 1, 2, 3, 4) then you'll have to provide an augmented array to the apply function:
var a = function() {
var args = [self.test];
for(var i = 0; i < arguments.length; i++) args[] = arguments[i];
return self.success.apply(self, args);
}
this.successdefined?