I am wondering what is the use of asObservable
:
As per docs:
An observable sequence that hides the identity of the source sequence.
But why would you need to hide the sequence?
Observables provide support for passing messages between parts of your application. They are used frequently in Angular and are a technique for event handling, asynchronous programming, and handling multiple values.
RxJS introduces Observables, a new Push system for JavaScript. An Observable is a Producer of multiple values, "pushing" them to Observers (Consumers). A Function is a lazily evaluated computation that synchronously returns a single value on invocation.
Angular makes use of observables as an interface to handle a variety of common asynchronous operations. For example: The HTTP module uses observables to handle AJAX requests and responses. The Router and Forms modules use observables to listen for and respond to user-input events.
In comparison to a regular Observable, a Subject allows values to be multicasted to many Observers. A Subject and its subscribers have a one-to-many relationship. A Subject can be an Observable as well as an Observer. They hold a registry of many listeners to multiple Observables.
The purpose of this is to prevent leaking the "observer side" of the Subject out of an API. Basically to prevent a leaky abstraction when you don't want people to be able to "next" into the resulting observable.
(NOTE: This really isn't how you should make a data source like this into an Observable, instead you should use the new Observable
constructor, See below).
const myAPI = { getData: () => { const subject = new Subject(); const source = new SomeWeirdDataSource(); source.onMessage = (data) => subject.next({ type: 'message', data }); source.onOtherMessage = (data) => subject.next({ type: 'othermessage', data }); return subject.asObservable(); } };
Now when someone gets the observable result from myAPI.getData()
they can't next
values in to the result:
const result = myAPI.getData(); result.next('LOL hax!'); // throws an error because `next` doesn't exist
new Observable()
, thoughIn the example above, we're probably creating something we didn't mean to. For one, getData()
isn't lazy like most observables, it's going to create the underlying data source SomeWeirdDataSource
(and presumably some side effects) immediately. This also means if you retry
or repeat
the resulting observable, it's not going to work like you think it will.
It's better to encapsulate the creation of your data source within your observable like so:
const myAPI = { getData: () => return new Observable(subscriber => { const source = new SomeWeirdDataSource(); source.onMessage = (data) => subscriber.next({ type: 'message', data }); source.onOtherMessage = (data) => subscriber.next({ type: 'othermessage', data }); return () => { // Even better, now we can tear down the data source for cancellation! source.destroy(); }; }); }
With the code above, any behavior, including making it "not lazy" can be composed on top of the observable using RxJS's existing operators.
A Subject
can act both as an observer
and an observable
.
An Obervable
has 2 methods.
Whenever you subscribe to an observable
, you get an observer
which has next, error and complete methods on it.
You'd need to hide the sequence because you don't want the stream source to be publicly available in every component. You can refer to @BenLesh
's example, for the same.
P.S. : When I first-time came through Reactive Javascript, I was not able to understand asObservable
. Because I had to make sure I understand the basics clearly and then go for asObservable
. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With