I try to write a function, that returns a promise version for some API (AgileCRMManager). The design of the api works pretty similar to request.
But i have some Problems with the handover of the Function. The Function have no access to the prototype of its own. I got following log output:
[Function: getContactByEmail]
[Function: getContactByEmail]
TypeError: this.getOptions is not a function
at getContactByEmail (/Users/Tilman/Documents/Programme/NodeJS/async_test/node_modules/agile_crm/agilecrm.js:116:24)
at /Users/Tilman/Documents/Programme/NodeJS/async_test/routes/portal.js:30:5
at restPromise (/Users/Tilman/Documents/Programme/NodeJS/async_test/routes/portal.js:29:10)
at Object.<anonymous> (/Users/Tilman/Documents/Programme/NodeJS/async_test/routes/portal.js:22:1)
at Module._compile (module.js:541:32)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:456:32)
at tryModuleLoad (module.js:415:12)
at Function.Module._load (module.js:407:3)
at Function.Module.runMain (module.js:575:10)
This is the part with getOptions from agile_crm:
ContactAPI.prototype.getOptions = function getOptions() {
this._options = {
host: this.domain,
headers: {
'Authorization': 'Basic ' + new Buffer(this.email + ':' + this.key).toString('base64'),
'Accept': 'application/json'
}
};
return this._options;
};
This is my Code (if i change restFunction with a.contactAPI.getContactByEmail, it works. But i want to have it for more functions):
var AgileCRMManager = require("agile_crm")
var a = new AgileCRMManager("user-domain",
"api-key",
"user-mail")
restPromise('ds@umzuege-selisch.de',a.contactAPI.getContactByEmail)
.then(console.log)
.catch(console.error)
function restPromise(data, restFunction) {
console.log(restFunction); // => [Function: getContactByEmail]
console.log(a.contactAPI.getContactByEmail); // => [Function: getContactByEmail]
return new Promise(function(fulfill, reject){
//a.contactAPI.getContactByEmail(
restFunction(
data,
function(data){
fulfill(data)
},
function(error){
reject(new Error(error))
}
)
})
}
Any Idea how i can hand Over the function and api will still work?
You've misunderstood how this
works in javascript. Normally I'd vote to close questions like this but this seems to be a specific use case that requires further explanation. For a full explanation of how this
works I'd suggest reading the answer from this question: How does the "this" keyword in Javascript act within an object literal? .
Now, the problem is that in js the value of this
depends on how you call a function. If a function is a method, this
resolves to the object the method belongs to:
a.foo = function () { console.log(this) };
a.foo() // should output `a`
But if the function is a simple function that is not part of an object then this
is either the global object (window in browsers) or undefined depending on strict mode. Note that js interprets weather or not a function is a method when you call the function. Not when you define the function. This has interesting consequences:
a.foo = function () { console.log(this) };
b = a.foo;
b(); // here b is a simple function because it's not something.b
// so the output is either the global object or undefined
This is what happens in this line of code:
restPromise('ds@umzuege-selisch.de',a.contactAPI.getContactByEmail)
You're passing a.contactAPI.getContactByEmail
as a function reference. Therefore it loses the fact that it's part of a.contactAPI
and instead becomes a simple function. This fact can be clearly seen by how you call the function:
restFunction( //...
Note that you're calling restFunction
which is a function reference to a.contactAPI.getContactByEmail
. Since it is called simply as restFunction()
instead of a.contactAPI.restFunction()
the this
in the function points to the global object (or undefined depending on strict mode) instead of a.contactAPI
.
There are several ways you can fix this.
Wrap a.contactAPI.getContactByEmail
in an anonymous function so you can call it with the proper this
:
restPromise( 'ds@umzuege-selisch.de', function(data,ok,err){ a.contactAPI.getContactByEmail(data,ok,err); } )
Use .bind()
:
restPromise( 'ds@umzuege-selisch.de', a.contactAPI.getContactByEmail.bind(a.contactAPI) )
Modify restPromise()
to accept an object instead of a function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.