How to handle / put multiple identical HTTP requests using RxJs?

I am making an Angular 4 app. Components are signed by Observable. Sometimes Observable calls the same URL. For example, "Refresh Access Token", if necessary, prior to any HTTP request. But if I make 3 different http requests, it will "update if needed", update the token 3 times.

So how do you do just one http to get the updated access token, and make the rest of the observables "wait" for the first? (I know "wait" is not a good word for Observables).

        public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
            return this.getAccessToken().mergeMap(accessToken => {
              return this.http.get(url, options);
            });
          }

      

//AND

this.get('www.myapi.com/one').subscribe(data=>console.log('one',data))
this.get('www.myapi.com/two').subscribe(data=>console.log('two',data))
this.get('www.myapi.com/three').subscribe(data=>console.log('three,data))

      

+3


source to share


2 answers


It looks like you can use an operator share()

that makes sure there is always only one subscription to the Observable source.

However, this will require you to restructure your code, because all observers must use the same instance share()

:



const sharedToken = this.getAccessToken().share();

public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
  return sharedToken.mergeMap(accessToken => {
    return this.http.get(url, options);
  });
}

      

+5


source


Use the forkJoin operator . If you are familiar with Promises, this is very similar to Promise.all (). The forkJoin () operator allows us to take a list of Observables and execute them in parallel. As soon as each Observable in the list emits a forkJoin value with the emission of a single Observable containing a list of all allowed values ​​from the Observables in the list

please go to the example below:

Import

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

      

Let's say you should get three pages



var pages:number[] = [1, 2, 3];

      

Or var pages:number[]=new Array(10).fill().map((v,i)=>i+1);

and then map them to observables array and forkJoin

Observable.forkJoin(
   pages.map(
      i => this.http.get('www.myapi.com/' + i)
        .map(res => res.json())
   )
).subscribe(people => this.people = people);

      

Go to Stack or forkJoin for more information.

0


source







All Articles