5

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?

2 Answers 2

5

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:

Sign up to request clarification or add additional context in comments.

4 Comments

I tried using flatMap(), but kept getting Property 'flatMap' does not exist on type 'Observable<string>'. on compile. Is this because my requestToken() method returns the token as a string on success?
In fact, it's because the flatMap operator i's an alias to the mergeMap one ;-) You need import it this way: import 'rxjs/add/operator/mergeMap';
The difference between flatMap and switchMap is that the first one doesn't the previous in-progress observable / request. In your case it's enough. SwitchMap is particularly useful for autocompletion (for example)
2

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

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.