If you have been following the development efforts of the Angular2 project, you have witnessed certain highs and lows - but it has been a fun ride. The latest version is only a Release Candidate and the team is getting closer to the final release. I’m really looking forward to that! I wanted to take a moment to highlight (IMO) one of the key services of Angular2 the
In AngularJs 1 the
$http) was based on promises and deferrals. In Angular2 we now rely on RxJS and the observable pattern. In my opinion this is a huge win! If you’re unfamiliar with Reactive Extensions in general, I suggest starting here. RxJS is the
As a developer you would have to use both the
ng.IHttpService and the
ng.IQService in combination to collaborate the deferral of the HTTP request and the promise that represented it. Consider the following:
In this example, we can easily see the interaction betwixt the
ng.IHttpService ($http) and
ng.IQService ($q) services. The
$q variable exposes a
.defer function that returns a deferred object.
||Resolved yielding the materialized value of type
||Rejected with the given reason|
The deferred object instance is passed into the fluent API’s of the
.error functions accordingly. This pattern works great, but is very limiting and repetitive. You end up writing a lot of boilerplate code and that isn’t very DRY. Let’s look at how this is approached with Angular2’s
http service using the observable pattern from RxJS!
To be fair, let’s implement the same functionality and public surface-area such that our example services are equivalent.
I am hoping that you noticed how much cleaner this code is, as well as how much more readable!
Now, I know what you’re thinking...these cannot possibly be the same examples, but they are in fact doing the same thing. Dependency Injection (DI) in Angular2 is a lot less error prone (no more magic strings) and way easier than it was in AngularJs 1. Simply do what you’d expect from any other common constructor-based DI framework, ensure that your desired
Http type is registered as a provider to the system. This happens by way of the
HTTP_PROVIDERS defined in as part of our bootstrapping of the app.component. More on that in another post. With modern
TypeScript we can define properties and fields, and their corresponding access modifiers right from within our constructors.
This exemplifies the comparisons in syntax between a simple constructor and the more verbose constructor.
Likewise, the following is true regarding public access modifiers.
Instead of the
.success invocation with a corresponding
deferred.resolve call, we now utilize the RxJS
.subscribe operators. Let’s look at these below:
||Transform the items emitted by an Observable by applying a function to each item|
||The Subscribe operator is the glue that connects an observer to an Observable|
Mapping is easy and we can leverage some of the
TypeScript language features to cast the JSON blobs returned from our services as strongly typed objects. The map operator is actually synonymous with the select operator, so if you’re more familiar with that terminology you can use it interchangeably.
Now that we have an understanding of how RxJS compares to the legacy pattern, we can take advantage of all the various benefits. Imagine with me that we have a need to implement retry logic, this would have been challenging with the legacy pattern but with the new pattern it’s as simple as saying
.retry. Consider the following:
Now imagine a scenario where a user is typing and you want to provide an autocomplete, you could use
.debounce to pause for a brief moment prior to sending the request. Likewise, we could apply a .filter that only takes action when a certain number of characters have been entered. Finally, we might utilize
.distinctUntilChanged to only execute the request once the values are actually different than they once were.
You could take advantage of
.range, etc… The list goes on and on, and this is the source for most of what you can take advantage.
Angular2 has a new implementation of their http service that relies on RxJS. The API uses observables and the observer pattern to allow for a fluent experience that is rich and robust. Getting started is straight-forward and simple. Before too long you’ll be taking advantage of the feature-full set of Reactive Extensions and thinking in terms of data streams. This mindset will make your life easier – trust me!