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))
source to share
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);
});
}
source to share
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);
source to share