cbierman
cbierman

Reputation: 399

Angular 2 - What to do when an Http request depends on result of another Http request

I'm having trouble figuring out how to use the result of an Http request to make another Http request.

I have a Service that requests and receives JSON Web Tokens from a backend API that looks like:

@Injectable()
export class JwtAuthorizationService {

  constructor(private http: Http) {}

  public requestToken(): Observable<string> {
    // Set dummy credentials.
    let body = this.setBody();
    let headers = this.setHeaders();
    let token = this.http.post(tokenUrl, body, { headers: headers })
      .map(this.extractData)
      .catch(this.handleError);

    // Return the Observable
    return token;
  }

  private extractData(res: Response): string {
    let body = res.text();
    return body || "";
  }

How can I now use the result of the requestToken() (an Observable) to make an another API call, authenticated with the JWT, and get the result back from that? Or maybe more simply, what do you do when one Http call depends on the result of another?

Upvotes: 5

Views: 3475

Answers (2)

Thierry Templier
Thierry Templier

Reputation: 202176

You could use the flatMap operator to do that:

this.authorizationService.requestToken().flatMap(token => {
  var headers = new Headers();
  headers.append('Authorization', `Bearer ${token}`);
  return this.http.get('...', { headers }).map(res => res.json());
});

What you could also do is to make this transparent by extending the HTTP class. In it, you could check the token validity and if it's expired, call the requestToken method.

See this question for more details:

Upvotes: 5

Angular University
Angular University

Reputation: 43087

You can for example use the switchMap operator if you have a network call that needs to use the result of a previous network call:

const combined$ = jwtAuthenticationService.requestToken()
    .switchMap(tokenBody => this.http.get('/someurl') );

This is the marble diagram:

// requestToken

|---------------T---| 

// second HTTP request

                   |------R--|

// combined$

|--------------------------R--|

The sequence goes like this:

  • subscription to requestToken occurs
  • token returns, first call observable completes
  • the result of requestToken is taken and the initial Observable is transformed via switchMap into a second Observable
  • if the initial observable had not completed, combined$ would have unsubscribed from it
  • a second observable is made for the second network call, that uses the result of the first
  • second call returns, second observable completes, combined$ completes

Upvotes: 2

Related Questions