Sumair Rasool
Sumair Rasool

Reputation: 23

unable to use promise in Observable in angular services

I have a wrap-http service which i use as wrapper on top of HttpClient. In wrap-http service i have a method

createHeaderOptions

which gets user token from storage service, adds token into header options and returns it. I call this method for every request. In createHeaderOptions AuthService.getLoggedUser() is a promise, when i add await and async with AuthService.getLoggedUser() it throws error with get, put, post, delete and patch methods where it is being called in this same service because their return type is Observable. How can i handle this?


wrap-http.service.ts

export class WrapHttpService {
  private static async createHeaderOptions(headers) {
    let user = {};
    await AuthService.getLoggedUser()
      .then((result) => {
        user = result;
      });

    if (!_.isEmpty(user)) {
      if (!headers) {
        headers = {};
      }
      headers[`Authorization`] = 'Bearer ' + user[`tokenInfo`];
      headers[`Accept`] = '*/*';
    }

    const httpOptions = {};
    if (headers) {
      httpOptions[`headers`] = new HttpHeaders(headers);
    }
    return httpOptions;
  }

  get(url: string, headers?: object): Observable<any> {
    return this.http.get(url, WrapHttpService.createHeaderOptions(headers));
  }
  post(url: string, data: object, headers?: object): Observable<any> {
    return this.http.post(url, data, WrapHttpService.createHeaderOptions(headers));
  }
  put(url: string, data: object, headers?: object): Observable<any> {
    return this.http.put(url, data, WrapHttpService.createHeaderOptions(headers));
  }
  patch(url: string, data: object, headers?: object): Observable<any> {
    return this.http.patch(url, data, WrapHttpService.createHeaderOptions(headers));
  }
  delete(url: string, headers?: object): Observable<any> {
    return this.http.delete(url, WrapHttpService.createHeaderOptions(headers));
  }
}

Any help here would be much appreciated.

Upvotes: 0

Views: 97

Answers (1)

enno.void
enno.void

Reputation: 6579

First of all you might want to use a HttpInterceptor for this instead passing the headers manually. https://angular.io/api/common/http/HttpInterceptor

If you want to do it manually it could look like this:

export class WrapHttpService {
  private static createHeaderOptions(headers) {
    return AuthService.getLoggedUser().then((user) => {
        if (!_.isEmpty(user)) {
          if (!headers) {
            headers = {};
          }
          headers[`Authorization`] = 'Bearer ' + user[`tokenInfo`];
          headers[`Accept`] = '*/*';
        }

        const httpOptions = {};
        if (headers) {
          httpOptions[`headers`] = new HttpHeaders(headers);
        }
        return httpOptions;
    });
  }

  get(url: string, headers?: object): Observable<any> {
    return from(this.createHeaderOptions(headers)).pipe(
      switchMap(headers => this.http.get(url, WrapHttpService.createHeaderOptions(headers));)
    )
  }

  /* ... */
}

Explanation: Rewrite createHeaderOptions to return a promise. Now use rxjs´s from method to create an observable from a promise, then use switchMap to switch to the observalbe which is returned by this.http.get method

Upvotes: 0

Related Questions