Skip
Skip

Reputation: 6531

"this" becomes uindefined in a function

I have the following angular2 component, where I implemented a listenerSelectedChanges() on an EventEmitter. I would like to unsubscribe from the events, when needed. For that purpose the idea was - to use a function instead of a lambda.

Now I faced the problem, that in my listenerSelectedChanges() function - the ".this" object becomes invalid.

Question: What is the lifecycle of a function in JS / Typescript? Can the function live longer, than its parent?

export class Auth0Component implements OnInit, OnChanges {

  @Input() selectedEnvironment: Environment;
  @Output() identityTokenReceived = new EventEmitter(); // component should use the emitter of the AWSService

  listenerSelectedChanges = function (idToken: string) {
    this.identityTokenReceived.emit(idToken);
  };


  // bind to the AWSservice emitter
  ngOnChanges(changes: SimpleChanges) {
    console.log(changes);

    if (this.selectedEnvironment !== undefined) {
      // would like to use listenerSelectedChanges() here
      this.selectedEnvironment.auth0Session.identityTokenReceived.subscribe(idToken => {
          this.identityTokenReceived.emit(idToken);
      });
    }

    // unsubscribe here
  }

}

Upvotes: 0

Views: 92

Answers (3)

dannybucks
dannybucks

Reputation: 2355

Define your function like this in order to keep "this" pointing to your component:

 listenerSelectedChanges = (idToken: string) => {
   this.identityTokenReceived.emit(idToken);
 };

And call normally:

this.listenerSelectedChanges()

Hier is the doc of that behavior:

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in current scope they end up finding this from its enclosing scope.

Copied from MDN -> Arrow functions

Upvotes: 2

Mohamad Mousheimish
Mohamad Mousheimish

Reputation: 1695

Try to Define a constant named self in the beginning of your method which contain the value of this. Then use it inside, where it's being undefined. Which means your code will be like this:

ngOnChanges(changes: SimpleChanges) {
    const self = this;
    console.log(changes);

    if (this.selectedEnvironment !== undefined) {
      // would like to use listenerSelectedChanges() here
      this.selectedEnvironment.auth0Session.identityTokenReceived.subscribe(idToken => {
          self.identityTokenReceived.emit(idToken);
      });
    }

    // unsubscribe here
}

Upvotes: 0

Poul Kruijt
Poul Kruijt

Reputation: 71941

Change your implementation to an arrow function to keep the correct this context:

listenerSelectedChanges = (idToken: string) => {
  this.identityTokenReceived.emit(idToken);
};

Upvotes: 3

Related Questions