Helper Functions for Doing Rx in Angular
So far in my playing around RxJS has been working nicely with Angular. There are three things I find myself doing when integrating the two:
- turning an Angular promise into an observable
- turning an Angular watch into an observable
- turning an Angular scope function call into an observable
Turning an Angular promise into an observable is pretty straight forward.
This is a pretty generic pattern for turning any promise into an observable – on success call
onComplete and on an error call
onError. I end up just attaching it to the
Why would you want to do this? The canonical example is a typeahead. When the user searches for a term you perform an asynchronous web request which fetches the potential completions. With a typeahead the user is constantly changing their search term which is triggering several asynchronous requests. One potential problem is if they search for “black” and then “black sab” you have no control over which web request will finish last and you don’t want to end up having the results for “black sab” overwrite the results for “black” by the requests finishing out of order.
switchLatest. This will take an observable of observables (mouthful) and switch so that only the latest observable sequence is returned.
The above code takes an observable of search terms,
terms, samples it every 250ms, and performs an asynchronous query to look up the artists. If the requests take more than 250ms we might get interleaving of the results which
switchLatest will elminate – we only see ordered responses. Then we select (map) the result to a list of artists. The end result is an observable of an array of artists which only contain the most recent results.
Angular watches are the observer pattern so pretty similar to an observable already. The difference is that they lack the composability of observables. As shown in the typeahead example above the composability is pretty nice.
To create an observable from a watch we just need a scope and an expression. We pass the expression directly to the watch call and then for the listener we call
onNext on the observable. Sticking with the typeahead example we could use this to produce the original sequence of terms.
This would produce the original observable stream of search terms from an
ng-model set to
Sometimes you also want to turn function calls on the scope into an observable. I use this one the least. The only example I have is when you are using
ng-change instead of
ng-model. I’m also not super happy with the syntax. The code is nearly identical to the watch example.
Using the exact same search terms example but this time instead using
ng-change set to
setTerm(term) in the view.
These are pretty short functions – nothing too special. Hope they help. Vive la Angular et RxJS!