jvrnt jvrnt - 2 months ago 10
TypeScript Question

Angular losing context when running function reference for a function of a base class

Let's say i have

CtrlOne
that extends
CtrlTwo
, and a
componentOne
that instantiated in
CtrlOne
template. Some code (i'm skipping most of the irrelevant code just so the problem will be clearer):

class CtrlOne extends CtrlTwo {
constructor() { super(); }
}

class CtrlTwo {

sayMyName(name: string) {
console.log(this.getMyLastName() + name);
}

getMyLastName() {
return 'squarepants';
}
}


This is the template associated with
CtrlOne
:

<component-one data-say-my-name="vm.sayMyName"></component-one>


And this is stateless
componentOne
:

angular.module('mymodule').component('componentOne', {
bindings: {
sayMyName: '&'
},
template: '<button data-ng-click="$ctrl.sayMyName()('spongebob')></button>'
});


On click, i successfully get to the function
sayMyName
of
CtrlTwo
, but it's refusing to recognize
this.getMyLastName
, throwing
TypeError: this.getMyLastName is not a function
.

If i just use
sayMyName
or
getMyLastName
directly from
CtrlOne
template, everything works fine. But if i use it trough the binding passed to
componentOne
, i get the error.

What am i missing here?

Answer

Class methods that are supposed to be used as callbacks should be bound to their context.

Like

class CtrlTwo {
    constructor() {
        this.sayMyName = this.sayMyName.bind(this);
    }
    ...
}

or

class CtrlTwo {
    sayMyName = (name: string) => { ... }
    ...
}
Comments