I am struggling in understanding why this snippet would lose the context of this ?
What I wanted to achieve is to remove one (first) argument from the function that's been executed which has been achieved. The problem is that right now I cannot access anything from the class instance scope. Does anyone have idea on what has happened here? I believe it could be related to double arrow method that's been used but I have no idea on how to fix it.
class Callback {
test = 'test';
callback(a) {
console.log(this);
console.log(a);
}
}
const callback = new Callback();
const serverAdapter = (cb) => (_, args, context) => cb(args, context?.req);
console.log("Having a context");
callback.callback('test');
console.log("Losing the context");
serverAdapter(callback.callback)(1,2,3);
outcome:
[LOG]: "Having a context"
[LOG]: Callback: {
"test": "test"
}
[LOG]: "test"
[LOG]: "Losing the context"
[LOG]: undefined
[LOG]: 2
Change this:
serverAdapter(callback.callback)(1,2,3);
to this:
serverAdapter(callback.callback.bind(callback))(1,2,3);
When you pass obj.foo as an argument, only a reference to the method is passed as a plain function and then when the function you passed it to calls that function, it's just called as a plain function, not as obj.foo() so there is no longer any reference to the original object.
There are multiple ways to solve this. Using .bind() is one such mechanism.
If you were really going to use this class as a callback manager, then you could build the binding into the callback class itself like this:
class Callback {
test = 'test';
constructor() {
// create bound method
this.callback = this.callbackOp.bind(this);
}
callbackOp(a) {
console.log(this);
console.log(a);
}
}
Then, you could just pass obj.callback as a callback and it would automatically be bound to obj for you.