Subscribing to observables one at a time!

I am new to Observables concept and I am trying to create a service which will take different observables from various clients and will fire the observables one a time. The use case is that I have a page where multiple http requests are being made and in order to avoid hogging up the server, I want to make one request at a time. Is there an easy way to do it?

I cannot use concat because I don’t want to merge the output to a single result. The result of each observable has to be returned to the respective client. https://multi-programming.com/creating-progressive-web-apps-using-angular

1 Like

Hi Angular dev here!

First of all there are a few points I want to bring up

  1. How and what Observables are.
  2. How Angular’s HttpClient service uses Observables to handle async requests.
  3. Techniques on “sharing” requests, and preventing asking for the same data over and over.

How and what Observables are

Observables are similar to Promises, except they can emit multiple values over time, there is much more to what and how you can use them, and the expansive operator library that allows you to do ** a lot** with Observables. (I won’t go into this sort of stuff here tho haha)

How Angular’s HttpClient service uses Observables to handle async requests.
Angular’s HttpClient service uses Observables to return and manage requests made using ajax requests. Promises would be just as capable to handle these tasks, but Angular uses Observables due to their ability to use all the rxjs operators. Something as simple as canceling a pending http request isn’t possible with promises, but you can get this out of the box with observables. (Use the async pipe)

Techniques on “sharing” requests, and preventing asking for the same data over and over.
The short answer is there are multiple ways to do this. from state management approaches like ngrx, ngxs and akita to more custom simpler approaches.

The simplest way to “share” the same data is to use the operator shareReplay and create some kind of cache for said data. Here is a method that caches the previous result for a given documentId. This will return the same document if the method is called with same id back to back, if you call it with a new id, we make a new async request.

MyService {
  private _documentId: string;
  private _document$: Document;
  constructor(httpClient: HttpClient) {}
  public getDocument(id: string) {
    if (this._documentId !== id) {
      this._documentId = id;
      this._document$ = this.httpClient.get('/document-url').pipe(shareReplay(1));
    }
    return this._document$;
  }
} 

This approach can be expanded to use map to provide a “local-copy” of the data allow you to cache every single type of document. Like any cache the question of “when do I clear” this will need to be addressed based upon your use case though.

Hopefully that helps in some way or form, if you need more help don’t be afraid to ask. I had a vague understanding of your use-case, so I might be off :slight_smile:

PS. I wrote the code off the top of my head, if there are syntax errors let me know ;D

1 Like

:beers: awesome explanation. Thanks