Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.then() is never called on Observable.toPromise()

I try to authenticate my backend calls with a token from angularfire2 authentication library. I subscribe to the authState to get the user token and add it as a RequestOption to my http request.

If I set a breakpoint in chrome debugger it executes the return lines in getAuthOptions() successfully, but after this.getAuthOptions().toPromise() the app calls neither the .then() nor the .catch() functions.

Is there an error with the Observable usage? Is there any other approach I can try?

  getPoints(): Promise<Object[]> {
    return this.getAuthOptions().toPromise()
      .then(options => this.http.get(this.baseUrl, options).toPromise())
      .then(_ => _.json().data)
      .catch(console.log);
  }

  getPointsFor(isin: String): Promise<Object> {
    return this.getAuthOptions().toPromise()
      .then(options => this.http.get(this.baseUrl + isin, options).toPromise())
      .then(_ => _.json().data[0])
      .catch(console.log);
  }

  private getAuthOptions(): Observable<RequestOptions> {
    return this.afAuth.authState.map(res => {
      if (res && res.uid) {
        const token = res.getIdToken(true);
        return new RequestOptions({
          headers: new Headers({
            Auth: `${token}`
          })
        });
      } else {
        return new RequestOptions();
      }
    });
  }
like image 737
Steffen Schmitz Avatar asked Jun 25 '17 21:06

Steffen Schmitz


People also ask

What does toPromise() do?

The toPromise function lives on the prototype of Observable and is a util method that is used to convert an Observable into a Promise . Inside this function we subscribe to the Observable and resolve the Promise with the last emitted value - attention - when the Observable completes!

How do you use toPromise?

toPromise method is Promise object. In order to use async/await style, you need at first wrap your code with async function, by prepending async keyword to function, and then with await keyword tell your code to wait for async operation. In your case it's http request.


1 Answers

The promise returned by the toPromise operator resolves when the observable completes or errors. The AngularFire2 authState observable does not complete, so the promise will not resolve unless an error occurs.

You can use the take operator to compose an observable that takes the first emitted authentication state and then completes:

import "rxjs/add/operator/take";

private getAuthOptions(): Observable<RequestOptions> {
  return this.afAuth.authState
    .take(1)
    .map(res => {
      if (res && res.uid) {
        const token = res.getIdToken(true);
        return new RequestOptions({
          headers: new Headers({
            Auth: `${token}`
          })
        });
      } else {
        return new RequestOptions();
      }
    });
}
like image 105
cartant Avatar answered Sep 20 '22 11:09

cartant