Angular2 Observable and Promise

Ned picture Ned · Apr 15, 2016 · Viewed 60k times · Source

I started using Angular2 Observable, but I can't find something similar to .then that I used with Promises.

This is what I want to accomplish.

code from header.component.ts

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo);
}

code from auth.service.ts

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .subscribe(user => {
    return new User(user);
  });

With promises, login function would return Promise, that would eventually transform to actual response from server. But with Observable this won't work.

Is there a way to do similar thing? I want to avoid need of putting subscribe inside component's login function. I want to be able to do all the work in service, and to return actual object to component.

Also, I tried to create Promise, with toPromise, but I keep getting toPromise is not a function.

p.s. _httpClient is my wrapper around angular2 http in which I prepare request by adding some headers etc.

edit

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .toPromise().    <-- i keep getting that it is not a function
  then(user => {
    return new User(user);
});

by doing this, my component will get object (which is what it need), and in service i could do additional things (like saving user to localstorage, once I logged him).

And I switched to Promise, because doing same with Observable is not working (or I am doing it wrong)?

I see that returned object is Observable (before calling toPromise), but I don't see toPromise function indeed.

Answer

G&#252;nter Z&#246;chbauer picture Günter Zöchbauer · Apr 15, 2016

When you call subscribe(...) a Subscription is returned which doesn't have a toPromise(). If you move the code from subscribe to map you can use toPromise() instead of subscribe

return this._httpClient.post('LoginAction', credentials)
  .map(res => res.json())
  .map(user => {
    return new User(user);
  }).toPromise();

and the caller will get a Promise where he can get the value using

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo)
    .then(result => {
      doSomething();
    });
}

but you get the same result if you omit `.toPromise() and the caller uses it like

public login() {
    this._user = AuthService.getInstance().login(this._loginInfo)
    .subscribe(result => {
      doSomething();
    });
}

where the only difference is subscribe() instead of then() and if the user of the library prefers the reactive style he will prefer using subscribe() like he is used to.