I have the following code inside my widget class that should manage a simple authentication popup.
private showPopupAuth(): void {
//...just show() and hide() some stuff...
this.getDiv().find('#cancel').unbind();
this.getDiv().find('#cancel').click(() => {
this.clearAuthPopups();
});
this.getDiv().find('#confirm').unbind();
this.getDiv().find('#confirm').click(() => {
let authRequest = new AuthRequest();
authRequest.userId = this.userId;
authRequest.pw = this.getDiv().find('#pw').val();
this.clearAuthPopups();
//...do stuff...
});
}
By pressing the cancel button a private function that closes it is called, and it works perfectly as expected. By pressing the confirm button I get the following error in console
MyWidget.ts:460 Uncaught TypeError: Cannot read property 'userId' of undefined
at HTMLButtonElement.<anonymous> (MyWidget.ts:460)
at HTMLButtonElement.dispatch (jquery.js:3)
at HTMLButtonElement.r.handle (jquery.js:3)
If I try to debug it and check Chrome > Sources > Scope window i see this:
inside cancel callback
- Local:
this
correctly points to MyWidget - Closure(showPopupAuth):
this
correctly points to MyWidget
inside confirm callback
- Local:
this
is undefined - Closure(showPopupAuth):
this
correctly points to MyWidget
If I run console.log(this)
inside showPopupAuth()
and inside the two callbacks i get, respectively:
> console.log(this)
< MyWidget { ..., userId: "the-user-id", ...}
> console.log(this)
< <button id="cancel">Cancel</button>
> console.log(this)
< <button id="confirm">Ok</button>
According to the console, this
becomes HTMLButtonElement even if I'm using fat arrows in both callbacks.
Why is this happening? What is going on? Looks like scope explorer and console are saying two different things, and both make no sense to me.
I know that I can solve the issue by simply declaring a let _this = this
and use it inside the callbacks but I would like to understand the root of the problem.
I already read TypeScript "this" scoping issue when called in jquery callback but it does not answer my question.
Update: as suggested i checked the generated js and everything looks ok
MyWidget.prototype.showPopupAuth = function () {
var _this = this;
this.getDiv().find('#cancel').unbind();
this.getDiv().find('#cancel').click(function () {
_this.clearAuthPopups();
});
this.getDiv().find('#confirm').unbind();
this.getDiv().find('#confirm').click(function () {
var authRequest = new AuthServiceBeans_1.AuthRequest();
authRequest.userId = _this.userId;
authRequest.pw = _this.getDiv().find('#pw').val();
_this.clearAuthPopups();
});
};