How can I continue refreshing an observable on button click when an observable error occurs in...

Discussão em 'Angular' iniciado por Nhut Truong, Abril 2, 2025.

  1. Nhut Truong

    Nhut Truong Guest

    I'm working on an Angular application where I fetch data from an API and display it using my custom state pipe and async pipe. There is a button to refresh the API call. However, if an error occurs, the observable stops emitting values and I can't refresh it anymore.

    state.pipe.ts

    import { Pipe, PipeTransform } from '@angular/core';
    import { Observable, catchError, map, of, startWith } from 'rxjs';

    type ObsState<T> = Observable<ObsStateAsync<T>>;

    export type ObsStateAsync<T> = { loading: boolean; result?: T; error?: any };
    @Pipe({
    name: 'state',
    })
    export class StatePipe implements PipeTransform {
    transform<T>(val: Observable<T>): ObsState<T> {
    return val.pipe(
    map((value: any) => ({ loading: false, result: value })),
    startWith({ loading: true }),
    catchError((error) => of({ loading: false, error }))
    );
    }
    }


    @Component({
    selector: 'app-root',
    template: `
    <button (click)="onRefresh()">Refresh</button>
    @let breedState = breeds$ | state | async;

    @if(breedState?.loading){
    Fetching ...
    }

    @if(breedState?.error){
    Error
    }

    @if(breedState?.result){
    @for(breed of breedState?.result;track $index){
    <div>
    {{ breed.attributes.name }}
    </div>
    }
    }
    `,
    imports: [StatePipe, AsyncPipe],
    })
    export class App {
    private readonly httpClient = inject(HttpClient);

    refresh = new BehaviorSubject<void>(undefined);

    getBreed$ = this.httpClient
    .get('https://dogapi.dog/api/v2/breeds') // Modify API endpoint to create an error
    .pipe(map((res: any) => res.data));

    breeds$ = this.refresh.asObservable().pipe(switchMap(() => this.getBreed$));

    onRefresh(): void {
    this.refresh.next();
    }
    }


    And I don't wanna do the catchError(()=>of([])) thing because the error needs to be displayed on the UI.

    Stackblitz to my problem

    Continue reading...

Compartilhe esta Página