Search code examples
angularangular-httpclient

Angular Http Caching and Race Conditions


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?


Solution

  • 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.