Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service call doesn't work inside error handler in Angular 5 [duplicate]

I have my HTTP calls inside a service as it should be, and in that service I inyect another service for error notifications.

For some reason, if I make the service notification call inside the catchError pipe it works fine, but if I make it inside an error handler function it doesn't work, and not only that, the rest of the code inside the error handler is interrupted.

Example:

// error message handler
// can not be used inside handleError()
private errorMessageGrowl() {
  this.messageService.add({
      severity: 'error',
      summary: 'Service Error',
      detail: 'An error has occurred'
  });
}

// error handler
private handleError(error: HttpErrorResponse) {

    // this works fine
    console.log('FLAG 1');

    // THIS DOES NOT WORK
    this.errorMessageGrowl();

    // THIS IS NEVER CALLED
    console.log('FLAG 2');

    // return an ErrorObservable with a user-facing error message
    return new ErrorObservable(
        'Something bad happened; please try again later.');
}

// http request
getService(): Observable<any> {

    return this.http.get<any>('./../../assets/data/example.json')
        .pipe(
            retry(4),
            catchError(this.handleError)
        );
}

It retries 4 times, it shows the "FLAG 1" log in console once, but the errorMessageGrowl() and the "FLAG 2" log is never shown.

Now, if I remove the notifications service from the error handler and call it inside the catchError pipe, it works perfectly:

// error handler
private handleError(error: HttpErrorResponse) {

    // this works fine
    console.log('FLAG');

    // return an ErrorObservable with a user-facing error message
    return new ErrorObservable(
        'Something bad happened; please try again later.');
}

// http request
getService(): Observable<any> {

    return this.http.get<any>('./../../assets/data/example.json')
        .pipe(
            retry(4),
            catchError((error) => {
                this.handleError(error);

                // it works outside handleError()
                this.errorMessageGrowl()
            })
        );
}
like image 309
David Prieto Avatar asked Jun 08 '26 23:06

David Prieto


2 Answers

By writing

catchError(this.handleError)

You lose your context (this doesn't point to the thing you expect)

replace it with

catchError((...args) => this.handleError(...args))
// OR
catchError(this.handleError.bind(this))

You're losing context inside catch. You need to call bind or use fat arrow function to call handleError()

catchError(this.handleError.bind(this)
// or
catchError((err) => this.handleError(err))
like image 31
Oleksandr Martyniuk Avatar answered Jun 11 '26 17:06

Oleksandr Martyniuk