Search code examples
javascriptrxjsobservablerxjs5subject-observer

How to create Observable from Subject without exposing the Subject to consumers in RxJs v5


I'm trying to return an observable from a function that uses Rx.Subject internally. Of course, as with any good API, the implementation details should be entirely abstracted from the consumer. However, using Subject.asObservable() it appears possible for any consumer to issue new values to all observers.

Example:

const subject = new Rx.Subject();
const observable = subject.asObservable();

observable.source === subject; // true

observable.forEach(value => console.log(value));
observable.source.next('Hello'); 
// Causes the forEach above to print "Hello"

So my question is, is there a built-in way to expose an Observable to consumers without giving them access to the original subject? If not this is clearly bad design on RxJs' part.

NOTE: This is for RxJS v5


Solution

  • The only way, that I know of, to truly encapsulate this would be to subscribe to the subject inside your function and and have another (either subject or custom obervable) returned that emits those value(s).

    But any operator (even the creation-operators like Observable.combineLatest(subject)) has some way to access the source.

    Another way to "solve" this would be to use Typescript, because the TS-compiler would tell you, that you cannot access a protected property source on Observable, since it is not a public attribute: https://github.com/ReactiveX/rxjs/blob/master/src/Observable.ts#L30 - of course in ES5 there is no such thing as "protected" and therefor it will be still accessible through the console e.g.