danday74
danday74

Reputation: 56936

rxjs subject / flatmap done right

Here is my code which works great. I call subject.next() which emits to an HTTP request stream which in turn emits the HTTP response. Bog standard pattern I believe. Catch provides the error handling I want.

My only question ... Can it be simplified?

let subject = new Subject<string>();

let httpStream$ = return subject.asObservable().flatMap((emit: any) => {

  return this.http[method](url, emit, this.options)
    .timeout(Config.http.timeout, new Error('timeout'))
    // emit provides access to the data emitted within the callback
    .map((response: any) => {
      return {emit, response};
    })
    .map(httpResponseMapCallback)
    .catch((err: any) => {
      return Observable.from([err.message || `${err.status} ${err.statusText}`]);
    });
}).publish().refCount();

I can emit to the subject using ...

subject.next(dataToEmit);

I can can subscribe to httpStream$ as usual.

As I said, everything works, but am I doing it right? Is there a simpler approach?

Upvotes: 1

Views: 774

Answers (1)

martin
martin

Reputation: 96891

There's not much to suggest when you code works. I guess you're using Subject because you need to be able to manually "refresh" the HTTP request.

I'd just suggest three things:

  • You don't need to use asObservable(). Subject already acts as an Observable. asObservable() is useful when you want to expose an Observable (return from a method) but hide the fact you're using a Subject internally. Since you're not returning the Subject you don't need to use asObservable().

  • You never need to use two map() operators one after another:

    .map((response: any) => {
      return httpResponseMapCallback({emit, response});
    })
    
  • Instead of .publish().refCount() you can use just share() which is its alias.

Upvotes: 1

Related Questions