Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular: Observable changes behavior when using a pipe and tab

I am working with Angular 10 and got the problem that the completion behavior of my observable changes, depending on wether I use a pipe or not. Here are the two relevant parts of my code.

auth.service.ts

...
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
...
register(email: string, password: string): Observable<RegistrationResponse> {
    return this.http.post<RegistrationResponse>(
      `${environment.API_URL}/users/register`,
      { email, password }).pipe(tap<RegistrationResponse>({
        next: (data) => {
          console.log('success - tap');
          if (data.jwt !== undefined) {
            this.setSession(data.jwt);
          }
        },
        error: () => {
          console.log('error - tap');
        }
      })
    );
}
...

auth.component.ts

...
this.authService.register(this.email, this.password).subscribe({
    next: (_) => {
      console.log('success');
      this.router.navigate(['/']);
    },
    error: (error) => {
      console.log('error');
      this.error = error.error || 'Error';
      this.loading = false;
    }
});
...

When the requests fails and I get an error response, it causes the following output (as expected):

error - tap
error

But when the requests succeeds, I get this:

success - tap
error                 <--- unexpected

=> How does this make sense, what am I missing?


Additionally, when removing the tap pipe, the completion handler gets called as expected.
register(email: string, password: string): Observable<RegistrationResponse> {
    return this.http.post<RegistrationResponse>(
      `${environment.API_URL}/users/register`,
      { email, password })/*.pipe(tap<RegistrationResponse>({
        next: (data) => {
          console.log('success - tap');
          if (data.jwt !== undefined) {
            this.setSession(data.jwt);
          }
        },
        error: () => {
          console.log('error - tap');
        }
      })
    );*/
}

Output:

success
like image 671
finn Avatar asked Jun 15 '26 06:06

finn


1 Answers

Some code in your tap next callback likely throws an error (check this.setSession(data.jwt)). Errors thrown in operators are caught and send as error notifications by RxJS. So the error callback in subscribe is called if an error is thrown in your pipe upstream.

like image 93
frido Avatar answered Jun 17 '26 23:06

frido