Angular Http Caching and Race Conditions
Asked Answered
C

1

5

I'm trying to figure out how to best solve a race condition in my app in the simplest way possible.

I have a route with two resolvers. The resolvers are:

GetBooksResolver

GetAuthorsResolver

Now, both Authors and Books have a type Genre that needs to be merged in.

Thus in both of the resolvers, you have a forkJoin:

// GetBooksResolver:
forkJoin(this.http.get('api/genres'), this.http.get('api/books'))
    .pipe(map(data => //merge datasets));

//GetAuthorsResolver
forkJoin(this.http.get('api/genres'), this.http.get('api/authors'))
    .pipe(map(data => //merge datasets));

I have a simple HTTP caching service that does correctly prevent the HTTP requests from firing again, but the initial race condition is still there.

As a result, you see two different api/genre calls

Any way to set up a caching interceptor so that this doesn't happen?

Centromere answered 11/12, 2018 at 4:7 Comment(1)
Could you set up another method that returns an observable from this.http.get('api/genres').publishReplay(1).refCount()? Reference hereOdy
W
6

As already suggested in the comments you can create a method that will call the service return a replay Observable like this:

public getGenres(): Observable<Genre> {
  return this.httpClient.get('api/genres').pipe(
    shareReplay(1)
  );
}

Then you call this method to get the replay Observable and use it in both forkJoin methods:

const genres$ = this.getGenres();
// GetBooksResolver:
forkJoin(genres$, this.http.get('api/books'))
    .pipe(map(data => //merge datasets));

//GetAuthorsResolver
forkJoin(genres$, this.http.get('api/authors'))
    .pipe(map(data => //merge datasets));

I have also created a working StackBlitz sample so you can see it in action.

Wen answered 16/12, 2018 at 11:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.