Fergal Rooney
Fergal Rooney

Reputation: 1390

Angular Async Pipe Re-Subscribe

My understanding of the Angular async pipe is that is subscribes to an exposed Observable for you in the HTML template. E.G

Component

export class TestComponent {
    let todos$: Observable<Array<Todo>>;

    constructor(private http: HttpClient) {}

    ngOnInit() {
        this.todos$ = this.http.get<Array<Todos>>(...)
    }
}

Template

<div *ngFor="let todo of todos$ | async">
    {{ todo }}
</div>

My understanding is that the HttpClient Observable will emit the following events for success:

next(value)
completed

and on error

error(error)
completed

When an observable emits a completed event, the subscription is closed.

Therefore, if you are subscribed to a cold observable like Angulars HttpClient Observable, how do you retry that HttpClient request?

The async operator does the initial subscription but will be closed as soon as the cold observable completes, how do you get the async operator to resubscribe if you want to execute it again? for example if you wanted to do a refresh of the data.

Upvotes: 1

Views: 3212

Answers (2)

Muhammed Albarmavi
Muhammed Albarmavi

Reputation: 24406

just reassign the todos$ this will trigger the http request again

component

export class TestComponent {
    public todos$: Observable<Array<Todo>>;

    constructor(private http: HttpClient) {}

    ngOnInit() {
     this.getTodos();
    }

    getTodos(){
        this.todos$ = this.http.get<Array<Todos>>(...);
    }
}

template

<button (click)="getTodos()" >Refresh 🚀</button>

demo 🚀

Upvotes: 7

Humberd
Humberd

Reputation: 2953

You have a retry and retryWhen operators. Play with them :)

https://rxjs-dev.firebaseapp.com/api/operators/retry

https://rxjs-dev.firebaseapp.com/api/operators/retryWhen

@edit

To refresh the data on success you can do it like this:


export class TestComponent {
    refresh$ = new BehaviorSubject(true);
    todos$: Observable<Array<Todo>>;

    constructor(private http: HttpClient) {}

    ngOnInit() {
        this.todos$ = this.refresh$
            .pipe(
                 switchMap(() => this.http.get<Array<Todos>>(...))
            )
    }

    refreshData() {
        this.refresh$.next();
    }
}

Upvotes: 2

Related Questions