Clement
Clement

Reputation: 4068

RxJS and AngularJS HTTP - how can I achieve this?

I'm writing a small utility function that wrap a call to AngularJS http.get with the necessary authentication headers:

get(endpoint: string): Observable {
    var headers = new Headers();
    this._appendAuthentificationHeaders( headers, this.user.credentials);

    return this.http.get(endpoint, { headers: headers })
            .map(res => res.json());
}

The point here is that if this.user is null, the method will just crash. So I have three options:

  1. Return null and check that return value on every call...
  2. Throw an exception
  3. Find a way to also return an RxJS Observable object that will directly trigger the error handler.

I would like to implement the third method, as it would allow me unify this method's behavior: It always returns an observable no matter what happen.

Upvotes: 5

Views: 929

Answers (2)

Thierry Templier
Thierry Templier

Reputation: 202326

If the user is null, you can simply return a raw observable that triggers an error:

if (this.user == null) {
  return Observable.create((observer) => {
    observer.error('User is null');
  });
}

(...)

or leverage the throw operator:

if (this.user == null) {
  return Observable.throw('User is null');
}

(...)

This way the second method of the subscribe method will be called:

observable.subscribe(
  (data) => {
    (...)
  },
  (err) => {
    // Will be called in this case
  }
);

Upvotes: 3

Tamas Hegedus
Tamas Hegedus

Reputation: 29946

I think the cleanest way would be to wrap the whole function body to an observable, as it will turn any accidental error to an observable error. Something like this:

get(endpoint: string): Observable {
  return Rx.Observable.defer(() => {
    var headers = new Headers();
    this._appendAuthentificationHeaders(headers, this.user.credentials);
    return Rx.Observable.just(headers);
  })
  .flatMap(headers => this.http.get(endpoint, { headers: headers }))
  .map(res => res.json());
}

However I still do not agree with http.get returning an observable instead of a promise. As these are single valued observables, your function could be a simple async function (sry, js instead of ts):

async get(endpoint) {
  var headers = new Headers();
  this._appendAuthentificationHeaders(headers, this.user.credentials);
  const res = await this.http.get(endpoint, { headers })).toPromise();
  return res.json();
}

Upvotes: 0

Related Questions