JBoy
JBoy

Reputation: 5755

Accessing 'this' from catch clause after firing a promise

Using the this keyword from within a catch clause after firing a promise reports "this" as being undefined.
What i want to do is simple, i have a Router object injected in the constructor of a service, from a method i fire an http request via a client, in case the response !=2* then i want to redirect the user.
For some reason, the current object (the service), seems gone, it looks like the catch is executed in another thread that is totally unaware of the service: The constructor:

constructor(private router: Router) { }

public sendRequestOrRedirect(){
var url = environment.url
var json = //someJSON here
return this.httpClient.patch(url,json).toPromise().then(res=>{
  return res;
}).catch(err => this.handleErrorResponse(err));

}

private handleErrorResponse (error: Response | any) {
      if(error.status == 401){
        this.router.navigate['/getout'];
        return Promise.reject(error.status);
      }
   }
  }

So the result of this.routerwill eventually throw an error saying that this is actually undefined. Any suggestion about how i could solve this and more importantly, why it happens?

Upvotes: 1

Views: 62

Answers (3)

JBoy
JBoy

Reputation: 5755

Fixed it with an inner function:

constructor(private router: Router) { }

    public sendRequestOrRedirect(){
    var url = environment.url
    var json = //someJSON here
    return this.httpClient.patch(url,json).toPromise().then(res=>{
      return res;
    }).catch((err) => {
          if(err.status == 401){
            console.log("Got a 401")
            this.router.navigate(['/getout'])
          }
        });
    }

Upvotes: 0

Manoz
Manoz

Reputation: 6617

It is all happening because when you do

.catch(this.handleErrorResponse);

Here this has limitations to its scope. It is currently a scope of catch function.

What you need is a lexical scoping

The ES6 arrow function syntax uses “lexical scoping” to figure out what the value of “this” should be. Lexical scoping is fancy way of saying it uses “this” from the surrounding code… the code that contains the code in question.

So when we do

.catch(err => this.handleErrorResponse(err)); //here this points to its module's scope

Upvotes: 2

user4676340
user4676340

Reputation:

Try using this syntax :

.catch(err => this.handleErrorResponse(err));

Upvotes: 0

Related Questions