AndyM
AndyM

Reputation: 1190

Observable subscribe always executes despite error

I'm building out an Angular website which chats to a bunch of API's and I've been following the Angular docs to try and use best practice for issuing HTTP request and handing subsequent success & failure.

I've hard-coded one of my API's to return a 500 error and I can successfully handle that 500 in the Angular app by using a catchError definition in the pipe after the HTTP service call, the code is as follows:

updateRemoteUserProfile(userProfile: UserProfile): Observable<UserProfile>{
    return this.http.put<UserProfile>(AuthService.userProfileApi, userProfile).pipe(
    catchError(this.handleError<UserProfile>('updateUserProfile', 'Error', 'Error updating profile', userProfile))
    );
}

private handleError<T> (operation = 'operation', title, notification, result?: T) {
    return (error: any): Observable<T> => {

      this.toastrService.error(notification, title);
      console.error(error);

      return of(result as T);
    };
}

The problem I'm running into is when I call the updateRemoteUserProfileMethod using the following code the subscribe method always executes and the success toast message pops up at the same time as the error one:

updateUserProfile(forename: string, surname: string){
    let userProfile: UserProfile = { forename: forename, surname: surname}
    this.updateRemoteUserProfile(userProfile).subscribe(() => {
        this.displayName = forename + ' ' + surname;
        this.displayNameChange.next(this.displayName);
        this.toastrService.success('Profile updated successfully', 'Success');
    });
}

I'm sure I'm missing something pretty simple and fundamental but it's all based on the Angular docs so I'm at a loss right now.

Many thanks

Upvotes: 0

Views: 591

Answers (2)

Suresh Kumar Ariya
Suresh Kumar Ariya

Reputation: 9754

We can also return EMPTY() observable, which will complete the observable by executing the subscribe complete method.

import {empty} from 'rxjs';

private handleError<T> (operation = 'operation', title, notification, result?: T) {
    return (error: any): Observable<T> => {

      this.toastrService.error(notification, title);
      console.error(error);

      return empty();
    };
}

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691625

Well, that's what catchError does: you're catching the error, so there's no error anymore.

If you want to propagate the error, either

  • don't catch it, or
  • use tap(null, handler) to propagate the original error but add a side-effect when it occurs (like logging or toasting the error), or
  • return throwError(...) from catchError instead of a of(...) to throw a different error than the original one

Upvotes: 3

Related Questions