4

I am making an Angular 4 app. Components are subscribing Observable. Sometimes Observable call the same url. For example 'refresh Access Token' if needed before any http request. But if I make different 3 http requests, it will "refresh if needed" 3 times the refresh token.

So how to make only one http get to get a refreshed access token, and make the other observables 'wait' for the first one ? (I know 'wait' is not the 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))
2
  • why not call the other observables inside the subscribe of the first one Commented Jul 31, 2017 at 12:55
  • Because I don't know which one will be called or not. And it is not very rxjs-ly. Commented Jul 31, 2017 at 13:20

2 Answers 2

5

It seems like you can use the share() operator that makes sure there's always only one subscription to the source Observable.

However this will require you to restructure your code because all observers need to use the same instance of share():

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

public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
  return sharedToken.mergeMap(accessToken => {
    return this.http.get(url, options);
  });
}
Sign up to request clarification or add additional context in comments.

Comments

-1

Use an operator called forkJoin. If you are familiar with Promises this is very similar to Promise.all(). The forkJoin() operator allows us take a list of Observables and execute them in parallel. Once every Observable in the list emits a value the forkJoin with emit a single Observable value containing a list of all the resolved values from the Observables in the list

please go through the below example:

Import:

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

Let assume you have to 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 into an array of observables and forkJoin

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

Please go Stack or forkJoin for more info.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.