tschoessi tschoessi - 1 year ago 71
TypeScript Question

Typescript: Setting members of object via callback fails strangely

I have a very strange issue for which I did not find the cause yet. I try to show a textbox component in Angular 2, which you can give a message, a label for the button and a callback that is invoked, when the button is clicked.

Here is my component:

selector: 'text-box',
templateUrl: './textbox.component.html',
styleUrls: ['./textbox.component.styl']
export default class TextBoxComponent implements AfterViewInit {
content: String;
btnCaption: String;
callback: () => void;

constructor(@Inject(TextBoxService) private service: TextBoxService) {

ngAfterViewInit(): void {

public show(message: String, btnCaption: String, callback: () => void) {
this.content = message;
this.btnCaption = btnCaption;
this.callback = callback;
// (1)
// set opacity 1

public btnOnClick() {
// (2)

public dismiss() {
// set opacity 0

Components are Singletons and cannot be injected, so you cannot simply invoke
on the component from the outside. Therefore I added a service and put a reference to the method into it (see the component's

export default class TextBoxService {
private showCallback: (m: String, b: String, c: () => void) => void;

public init(showCallback: (m: String, b: String, c: () => void) => void) {
this.showCallback = showCallback;

public show(message: String, btnCaption: String, callback: () => void) {
this.showCallback(message, btnCaption, callback);

It is invoked by another service like this:

'Wollen Sie einen Kredit aufnehmen?',
'Ja', () => {
this.activatedEvents.set(event, ziel);
this.inputService.kreditInput.summe = ziel.getPrice() - ziel.getLiquidFunds();
this.inputService.kreditInput.startdatum = date;

However, the text does not update when the button above is called, neither is the listener attached to the button (showing
this.callback() is not a function
). I debugged it (put
s on (1) and (2) in the component) and found out, that both methods are correctly called. On (1) the members
are correctly set - but on (2), these members are undefined!

I tried replacing the fat-arrow-syntax with
-syntax but with no success. I also tried hard-coding the string inside
but when accessing it via buttonClick, it's still undefined.

It seems like on (1) and (2) there are two different objects accessed. I have no idea what the reason for this behaviour could be. Any ideas?

Answer Source

Class prototype methods that are supposed to be passed as callbacks by design (as in this.service.init(this.show)) should be defined as arrow class properties:

public show = (message: String, btnCaption: String, callback: () => void) => { ... };

Or be bound on class construction:

constructor(@Inject(TextBoxService) private service: TextBoxService) {
  this.show = this.show.bind(this);

Alternatively, decorators may be used for neater syntax, e.g. @autobind from core-decorators.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download