Reference 'this' is null on $rootScope.$on

Viewed 200

Declared the following constructor in my Typescript AngularJS controller.

static $inject: Array<string> = [
    '$rootScope',
    'BookingRepository'
];
constructor(
    $rootScope: ng.IRootScopeService,
    bookingRepository: soft.data.BookingRepository
) {
    super();

    this.$rootScope = $rootScope;
    this.$rootScope.$on('accessController_onNavAccessSelected', this.accessController_onNavAccessSelected);

    this.bookingRepository = bookingRepository;
}

BUT when accessController_onNavAccessSelected is called, I'm getting null when I reference 'this'. I'm expecting the instance of the controller.

// Listening Events
accessController_onNavAccessSelected(event: ng.IAngularEvent, accessViewModel: soft.data.AccessViewModel): void {
    console.log(this);
}

What did I missed? Or How do I get a reference on the instance of my controller?

2 Answers

The context of the keyword this changes when using callbacks.

To prevent that, add .bind(this):

this.$rootScope.$on('accessController_onNavAccessSelected', this.accessController_onNavAccessSelected.bind(this));

or just use arrow function of ES6:

accessController_onNavAccessSelected = (event: ng.IAngularEvent, accessViewModel: soft.data.AccessViewModel) => {
    console.log(this);
}

Try to change accessController_onNavAccessSelected declaration this way:

accessController_onNavAccessSelected = (event: ng.IAngularEvent, accessViewModel: soft.data.AccessViewModel): void => {
    console.log(this);
}

Or use var self = this workaround:

var self = this;
accessController_onNavAccessSelected(event: ng.IAngularEvent, accessViewModel: soft.data.AccessViewModel): void {
    console.log(self);
}

Or you can force to specify exactly this, you needed, with the help of bind:

this.$rootScope.$on('accessController_onNavAccessSelected', this.accessController_onNavAccessSelected.bind(this));
Related