3

I have a method for handle our errors from http requests and it looks like this

public handleError(err: any, caught: Observable<any>): Observable<any> {

  //irrelevant code removed
  this.logger.debug(err);//example of problem 
  return caught;
}

It is invoked like this (example method, but shows the error)

  public makeHttpCall() {
    this.http.get("http://api.exmaple.com/getsomedata")
      .map(r=> r.json())
      .catch(this.handleError);
  }

The problem with the above code is that when calling this.logger.debug(err) in the handleError method this no longer refers to the class the http call was made from but references the CatchSubscriber.

See here: example of this

So i change .catch(this.handleError); to .catch(this.handlError.bind(this));

This works, now when i call this.logger.debug this refers to the correct object. The problem is, the http request gets called over and over and over, see here:

enter image description here

This only happens after applying .bind(this)

I can't figure out why this is happening

*********EDIT*********

Change from .catch(handleError) to .catch((a,b)=>handleError(a,b)) fixes the reference of this but the http request just gets spammed over and over, but only when the request fails. If the request succeeds it only happens once.

Steven Yates
  • 2,400
  • 3
  • 30
  • 58
  • does this solve your problem http://stackoverflow.com/questions/36227996/angular2-getting-confused-with-observable-catch-closure-scope ? – Harry Ninh Oct 20 '16 at 09:05

1 Answers1

3

When you pass a function with .catch(this.handleError); it loses its context this. See Why do I lose the context of this in Javascript?

Most easily you can fix this by wrapping the function call into a closure.

.catch((err, caught) => this.handleError(err, caught));
Community
  • 1
  • 1
martin
  • 93,354
  • 25
  • 191
  • 226
  • This does fix the `this` reference but the request still happens over and over. – Steven Yates Oct 20 '16 at 09:30
  • Of course, you return the original Observable that threw the error in `handleError()` and `.catch()` operator resubscribes to it. That's what `catch()` does by design https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/catch.md – martin Oct 20 '16 at 09:45
  • Thanks @Martin, I didn't see that "Continues an observable sequence that is terminated by an exception with the next observable sequence." So how do you prevent it from continuing? Returning null will throw and error. – Steven Yates Oct 20 '16 at 10:08
  • @StevenYates You prevent it by not using `catch()` operator if you don't need its functionality. So the question is why you're using `catch()` in the first place. Another option is to return a dummy Observable for example `Observable.of(null)`. – martin Oct 20 '16 at 10:27
  • I am using catch to log errors. Maybe I'm not using the correct method, but I just need to log anything that goes wrong with a request. Should I be using another method? – Steven Yates Oct 20 '16 at 10:28
  • @StevenYates Then you shouldn't be using `catch()` at all. Use `subscribe()` method instead here http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-subscribe or – martin Oct 20 '16 at 10:52