0

I am trying to avoid the nested subscription in request to the backend. I need to login, then get a service token based on the response of the login, then get a encryption token based on the service token.

I have seen about concatMap but i am not sure how to use the first response in the second request or third

  this.rest.CallLogin(this.data).pipe(
            concatMap(serviceToken => this.rest.GetServiceTicket(1stresponse.headers.get('Location'))),// dont know how to get the 1st response from CallLogin
            concatMap(tokenResponse => this.rest.getEncryptToken(serviceToken)),

        );
MaynorSong
  • 630
  • 7
  • 15
  • Your example doesn't look valid. Your first `concatMap` doesn't return observable (should be `tap`?). You also don't use `serviceToken` in your second request, you send there `this.data` is that correct? – Ludevik Aug 01 '19 at 05:37
  • I undestand. and I have modified it accordently. but how can I do it then? – MaynorSong Aug 01 '19 at 06:33

3 Answers3

0

You can use flatMap in place of the nested subscriptions.

import { flatMap } from 'rxjs/operators';

this.rest.CallLogin(this.data).pipe(
        flatMap((serviceToken) => {
            //serviceToken is the response of first call
            return this.rest.GetServiceTicket(serviceToken.headers.get('Location'))
        }),
        map((tokenResponse) => {
            //tokenResponse is the response of second call
            this.rest.getEncryptToken(tokenResponse)
        });
user
  • 568
  • 5
  • 19
0

I ended up using SwitchMap

 this.rest.CallLogin(this.data).pipe(
        switchMap((response: any) => {
        this.data.requestUrl = response.headers.get('Location');
        return this.rest.GetServiceTicket(this.data) // serviceticket
        }),
        switchMap((serviceticket) => {
            return this.rest.getEncryptToken(serviceticket.body) // tokenResponse
        }),
        //continue doing requests or stuff
        switchMap((tokenResponse) => {
            encryptToken = tokenResponse;
            ///...                
        }),
MaynorSong
  • 630
  • 7
  • 15
-1

If i understood correctly then you only want to chain the calls and use the response header from the first response. For that you need to use observe on response in your first call:

this.rest.CallLogin(this.data, {observe: 'response'}).pipe(
    concatMap(loginResponse => this.rest.GetServiceTicket(loginResponse.headers.get('Location'))),
    concatMap(serviceTicket => this.rest.getEncryptToken(serviceTicket)),
);
Ludevik
  • 6,954
  • 1
  • 41
  • 59