Observables?
Observables are the basic building block for many of the
things in the RxJS library. What it
essentially boils down to is a continuous stream of values sent from an emitter
to a listener. Observables help you
define how the data is received, mapped, and emitted to these listeners called observers.
Observables are kind of like a more powerful Promise, and
observers are the things that execute after the “.then()”.
Why use it?
The two main differences between observables and promises
are the ability to tear down and only calling methods when there is a
subscriber. Additionally, certain
observers can unsubscribe or stop listening to the observable. These two things don’t necessarily sound that
important, but they have very large practical effects.
For a simple one off http call, it is simpler to write a
promise to handle the data output and call .then() to catch it and handle it. The problem is when use cases get more and
more complicated, then promises stop working as intended. Race conditions start appearing, followed by
memory leaks.
Lazy requests
This meant that if you do not call .subscribe() in your
class or | async in the html then the observable will not fire. If you are new to observables, this will
undoubtedly trip you up and give you some heartache. However, it is a neat feature that allows you
to modify your code so that you can removed and add observers. When you have none, then your http calls aren’t
firing.
Remember that if you have multiple observers, then you
should apply .share() to your observables, or the function will run multiple
times.
Asynchronous calls
Http now uses observables by default instead of promises
like in AngularJS. For the most part the
code looks similar.
In AngularJS,
//in service
function httpCall() {
return $http.get(url);
}
//in controller
function doSomething() {
service.httpCall().then(
function(data){//do
something with data},
function(err){//error
handling}
);
}
In Angular
//service
function httpCall() {
return this.http.get(url)
.catch(//error
handling function);
}
//in component
function doSomething() {
service.httpCall().subscribe(res=>
{
//do
something with data
});
}
However, we gain to use observable operators directly on our
response object, and we can pass in an interface for type checking on our
observables to use elsewhere in our code.
If we add another type of Observable called Subject, then we
can effectively manage which http call will be shown to the user.
private subject = new
Subject<any>();
this.entries = this.subject
.switchMap((data) => {
//if
data is not empty switch to a new doSomething Observable, else empty observable
return data ? this.service.doSomething(data):
Observable.of<Type[]>([])})
.catch(error => {
//empty observable
return Observable.of<Type[]>([]);
});
In this use case, we call the same api endpoint with http
requests, but we provide different parameters to it based on user input. This allows us to call .next(//latest user
input) on subject, which in turns will deconstruct observables for old http request. This is most useful for searches such as
google instant, where a new http request is spawned every letter. It also gives us the freedom to apply
restrictions on how often these calls will be made, such as a 100ms delay or
waiting for unique input.
Other uses
Observables can be used for form validation, emitting data
between components, and a lot of other things other than async calls. There is a whole slew of methods that allow
you to manipulate the data and reorganize it to your heart’s desire. It is also more maintainable.
If anything is unclear, then leave a comment. I probably didn’t do the best job of
explaining it.
Peter
No comments:
Post a Comment