1

I have created a wrapper for angular 2 http service which has a post method as below. It returns an observable.

post(url:string, data:any, headers:any, animation:boolean):any{

    let thisObject = this;

    if(animation!=false) {
        thisObject.emitCallStateChange(true);
    }

    return this._http.post(url,data,headers).finally(function(){
        thisObject.emitCallStateChange(false);
    });

}

And i consume it like so:

return this._http_service.post(ConfigService.BASE_URL+'api/auth/forgotpass',email,{
        headers:headers
    },true);

What i want to do is to perform a GET for csrf validation request and append csrf token before returning this observable in the post method. So, i tried to wrap one observable within another like below:

this._http.get("api/getCsrf").subscribe(csrf=>{

        let body = csrf.json();

        data += "&_csrf="+body._csrf;

        console.log(data);

        return this._http.post(url, data, headers).finally(function () {
            thisObject.emitCallStateChange(false);
        });

    });

But it does not work for the obvious reason that it needs to return an observable. I need a way to return the final observable with the post request once the request for csrf completes. Is there a way i can chain observables and only return one of them?

xmaestro
  • 1,084
  • 2
  • 16
  • 44

1 Answers1

2

You could leverage the flatMap operator for this:

this._http.get("api/getCsrf").flatMap(csrf=>{
  let body = csrf.json();
  data += "&_csrf="+body._csrf;

  console.log(data);

  return this._http.post(url, data, headers).finally(() => {
    thisObject.emitCallStateChange(false);
  });
});

});
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • 1
    I was just going to link your answer on this one :) http://stackoverflow.com/questions/36712659/angular-2-two-backend-service-calls-on-success-of-first-service/36712707#36712707 – eko May 06 '16 at 07:44
  • 1
    Thanks! Yes, it's definitely related ;-) – Thierry Templier May 06 '16 at 07:46
  • @ThierryTemplier I'm already using rxjs npm package. Do i have to add reactive extensions separately? Because, this operator is not part of rxjs – xmaestro May 06 '16 at 08:04
  • No that's fine! You need to import the operator: globally or one by one. See this question: http://stackoverflow.com/questions/34515173/angular-2-http-get-with-typescript-error-http-get-map-is-not-a-function-in/34515276#34515276. – Thierry Templier May 06 '16 at 08:14
  • For `flatMap`, it's a bit special since it's an alias of the `mergeMap` one. You need to import the following to only import it: `import 'rxjs/add/operator/mergeMap';` ;-) – Thierry Templier May 06 '16 at 08:16
  • 1
    Oh. Thanks. They should perhaps mention it somewhere. Perhaps i missed it :D – xmaestro May 06 '16 at 08:38
  • Yes, it's not so obvious and `flatMap` is something common ;-) – Thierry Templier May 06 '16 at 09:56