Using ShareReplay() and to cache result of observable - how to refresh and use new value in...

Discussão em 'Angular' iniciado por Billy, Novembro 15, 2024.

  1. Billy

    Billy Guest

    I am using shareReplay() to cache an http call so it isn't repeated. However, at some point, I need to refresh the API call. Following various suggestions in stackoverflow, I introduce a Subject, so something like this:

    private _refreshResponse$ = new BehaviorSubject<void>(undefined);

    public response$: Observable<any> = this._refreshResponse$.pipe(
    switchMap(() => this.http.get<any>(this.apiUrl)),
    map((o) => o.message),
    shareReplay(1)
    );

    constructor(private http: HttpClient) {
    this.response$.subscribe();
    }

    public onRefreshClick() {
    this.refreshResponse();
    }

    public refreshResponse() {
    this._refreshResponse$.next();
    }


    And calling onRefreshClick() does indeed call the API again.

    I introduced a new method to do some more work. I want to make an http call first, which will then call refreshResponse(), and then some work with the new value. Something like the following:

    public onDoSomeWork() {
    // just create an observable... imagine it is an http call or something
    this.fakeHttpCall()
    .pipe(
    tap(() => this.refreshResponse()),
    switchMap(() =>
    this.response$.pipe(
    take(1),
    tap((o) => console.log(o))
    )
    )
    )
    .subscribe();
    }


    But, of course, refreshResponse() does not wait for the returned value, so the value I get from response$ immediately after it is the previous value, NOT the new value. How can I "wait" for the new value.

    Here's a demo: https://stackblitz.com/edit/angular-y2dtlg . The "response" is displayed in the browser (just a url from some random API I found). If you open the console, and click the "Work" button, it will refresh the URL displayed, and also write a URL to the console.log. But the console.log value is the previous value, not the updated one.

    Note: I don't want to do the "console.log" in the this.response$.subscribe(() => ...) method.

    Thanks in advance!

    Continue reading...

Compartilhe esta Página