I am having trouble figuring out how to pass the objects method rather than sort "generic prototype" method when doing callback.
function Client() {
this.name = "hello";
}
Client.prototype.apiCall = function(method, params, callback) {
callback();
}
Client.prototype.onLogin = function(error, data) {
console.log(this.name);// undefined!!!!
}
Client.prototype.start = function() {
var self = this;
self.apiCall('rtm.start', {
}, self.onLogin) // passing of method like this does not work.
}
I am passing the onLogin method but well it does not work. This is code I have re-written. Previously I nested all methods inside the Client function but well, I learned that that is not the way to do it so now I am trying using prototype.
I know there is some solution "binding" the onLogin function inside the Client() function but well I want to understand the issue.
The call() allows for a function/method belonging to one object to be assigned and called for a different object. call() provides a new value of this to the function/method. With call() , you can write a method once and then inherit it in another object, without having to rewrite the method for the new object.
Yes. The print( ) function takes another function as a parameter and calls it inside. This is valid in JavaScript and we call it a “callback”. So a function that is passed to another function as a parameter is a callback function.
The callback is a function that's accepted as an argument and executed by another function (the higher-order function). There are 2 kinds of callback functions: synchronous and asynchronous. The synchronous callbacks are executed at the same time as the higher-order function that uses the callback.
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.
You need to bind the apiCalls context to the callback using bind:
Client.prototype.apiCall = function(method, params, callback) {
var bound = callback.bind(this);
bound();
}
Otherwise, the this within onLogin is set to the global object.
See Call, Apply And Bind for further details.
Basically
.bind(obj)returns a function which, when called, will internally use(obj)asthis.
So you create this bound and then you call it.
You can use call or apply to bind this, see snippet. I've modified your code for demonstration purposes. Hope it clarifies things for you
function Client() {
this.name = "hello";
}
Client.prototype = {
apiCall: function(method, params, callback) {
try {
var trial = method.call(this, params);
callback.apply(this, [null, trial]);
} catch (e) {
callback.apply(this, [e, null]);
}
},
onLogin: function(error, data) {
if (error) {
Helpers.report('<b style="color: red">' +
'An error occured!</b> <i>' +
error.message + '</i>')
} else {
Helpers.report(this.name, ' (data.result = ' + data.result + ')');
}
},
start: function() {
Helpers.useCSS(1);
// error from this.rtm.start
Helpers.report('Command: <code>', 'this.apiCall(this.rtm.start, {will: \'not work\'}, this.onLogin);','</code>');
this.apiCall(this.rtm.start, {will: 'not work'}, this.onLogin);
// this.rtm.works is ok
Helpers.report('<br>Command: <code>',
'this.apiCall(this.rtm.works, {will: \'work\'}, this.onLogin);',
'</code>');
this.apiCall(this.rtm.works, {
will: 'work'
}, this.onLogin);
},
// --------------------------------
// added rtm for snippet demo
rtm: {
start: function(params) {
return anerror;
},
works: function(params) {
return {
result: 'worked, <code>params: ' + JSON.stringify(params) + '</code>'
};
}
},
};
new Client().start(); //<= here
<script src="https://rawgit.com/KooiInc/Helpers/master/Helpers.js"></script>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With