Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 can not access this on observable callback

Tags:

angular

I have the following code:

onLogin(): void {

  this.message = "loading";

  this.api.login("username", "password")

    .subscribe(
      this._processData,
      this._logError,
      //error => { this._logError(error); },
    );

}

private _logError(data) {
  console.log(data);
  this.errorMessage = data.message;
};

When I uncomment the line with //error -> and comment the line above, everything works fine.

It would be nice if there is a direct call solution where I give the function directly.

Any thoughts?

like image 889
Bas van Dijk Avatar asked Dec 25 '22 10:12

Bas van Dijk


2 Answers

I think that it's a problem related to the use of the this keyword itself within JavaScript and TypeScript. See this link: https://github.com/Microsoft/TypeScript/wiki/'this'-in-TypeScript.

You can try to use the bind method, as described below:

onLogin(): void {
  this.message = "loading";

  this.api.login("username", "password")
    .subscribe(
      this._processData.bind(this),
      this._logError.bind(this)
    );
}

private _logError(data) {
  console.log(data);
  this.errorMessage = data.message;
}

Hope it helps you, Thierry

like image 70
Thierry Templier Avatar answered Dec 28 '22 09:12

Thierry Templier


When I uncomment ... everything works fine

Well, your _processData() method must not not be trying to read or write to any component property, since it will not have the proper/expected this context. With .subscribe(this._processData, ...), the this context in _processData() will be a Subscriber object, not your component.

I suggest you use the arrow function for both the success and error callbacks to get the "same lexical this as the surrounding code" -- i.e., to get this to be the component:

.subscribe(
  data  => this._processData(data),
  error => this._logError(error),
);

I find this to be cleaner than using bind().

like image 37
Mark Rajcok Avatar answered Dec 28 '22 09:12

Mark Rajcok