3

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

Adam Arthur
  • 409
  • 3
  • 10

1 Answers1

1

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.

olsn
  • 16,644
  • 6
  • 59
  • 65
  • Appreciate the answer! Unfortunately I'm not working in a Typescript environment. Is there a valid, non-hacky use case for accessing the source from the consumer of an observable? That should be an explicit opt in. It's totally possible to encapsulate state in JS, so I don't buy that the source has to be exposed, or at least that the default mechanism for exposing observables to consumers should expose it. – Adam Arthur Dec 22 '16 at 01:41
  • That is absolutely correct that there are valid ways in JS to do that - i your best bet would be to open a github issue. From what I know is that rxjs5 was built with TS in mind, but this gets opinionated very quickly, which this is the wrong place for. – olsn Dec 22 '16 at 06:46