Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 398
MattEnth Avatar asked Dec 11 '18 04:12

MattEnth


People also ask

How to caching HTTP requests in angular?

In an angular application the better way to achieve the caching is to use HTTP interceptors. As their name suggests it allows us to intercept HTTP messages, with the help of which we can change the HTTP requests or the HTTP responses. Hence it a better option for caching the HTTP requests.

What is caching in HTTP and how does it work?

This is called caching. In HTTP, not all requests are cached. POST, PUT, and DELETE requests are not cached because they change the data in the server. POST and PUT add data to the server while DELETE removes data from the server. So we need to process them every time they’re requested without caching them. GET requests can be cached.

What is a cache request and why is it important?

Caching HTTP requests helps to optimize your application. Imagine requesting a piece of data from the server every time a request is placed, even if the data has never changed over time.

What are the hardest things in angular?

Though angular has so many things defined, still there are some things that you have to figure out on your own. “There are only two hard things in Computer Science: cache invalidation and naming things.”, Caching things is very easy but clearing the cache is difficult.


1 Answers

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.

like image 176
AlesD Avatar answered Oct 11 '22 20:10

AlesD