Reactive Extensions for Javascript (RxJs)
While I was working in Cronom, at 14 June 2013, I wrote an article related to Reactive Programming. Here is the link (It’s written in Turkish but give google translate a try); http://blog.cronom.com/reactiveextensios-javascript
Well, I must critisize; where is the version? :) Looks like I forgot to write version of RxJs libraries that I’ve used. At least there is date stamped. Well, some links are broken too. It is definately outdated.
I beleive that a person should carry his/her experiences to the future: Experiences with success is good anyway, on the other hand, bad ones should be the lessons learned for future. And, the person should read his/her history in future and loop the same strategy through it. This is the way how a person could evolve in good way only. So, here comes an important question: what will my first article be about? :)
So, I looked my past and saw that I had outdated articles. I’ll evolve. My first article will be the updated version of the same article. It’ll be in english, links will be fixed, RxJs versions will be added and will be re-designed with Medium. Here we go…
- Some Information
- General Usage
- On the way of AutoSuggesting TextBox
- AJAX
- Results
- References
1. Some Information
The reactive programming model has come alive with Microsoft’s new Reactive Extensions .Net library. Using Observer pattern in it’s basics, this model is independent against any platform and programming languages. As a matter of fact, we can easily apply this pattern in Java, Objective-C, C++ and C#. Observer design pattern can also be applied in Javascript language. There is even a similar version of the Reactive Extensions library for Javascript. This Javascript library is known as RxJs on the internet .
The RxJs library has a very similar use to the Rx library for .Net. We will refer to the details, but it will be helpful to mention RxJs’s historical process. The Rx project was hosted on GitHub for the first time and then joined the Microsoft community via CodePlex. RxJs is a library developed in parallel with Rx. There are also examples showing how observer design patterns are implemented in other software languages in related links. I would recommend your review.
The RxJs library is available on both GitHub and CodePlex as mentioned before. You may also want to review the MSDN page for tutorials and videos .
Don’t forget that RxJs is a Javascript library. In this case, the restrictions or freedoms of Javascript are also valid for this library. I think it would be useful to start with comparisons between C# and Javascript versions.
Notes
RxJs consists of 8 Javascript libraries and it can be installed separately via NuGet. These libraries are;
Only the Main library is required, and others are optional. You can also use the various libraries developed for the integration of RxJs, which makes it easier to use. For example, if you have already used jQuery in your application, it would be very useful to use the RxJs-jQuery library, which provides compatibility with RxJs. Here is the list of libraries that provides compability with many other popular Javascript libraries;
2. General Usage
In order to use RxJs, install RxJS-Main nuget package and then add the script tag to HTML. Using the cdnjs would be a valid alternative. In my code samples I’ve used RxJs 2.1.2 version and preffered to use cdnjs references.
In this example an observable “KeyUpEvent” is created. It delegates the “keyup” event of the “WikipediaSearch” text input. Now let’s compare it’s usages under different conditions.
So let’s discuss fromJQueryEvent and fromHTMLEvent functions. Suppose we’re going to contribute to RxJs with our new libraries. It’s simple; just implement Observable pattern for the DOM events of the given elements. There you go;
We simply have a library that we can apply Observable pattern; so things are easy when we want to develop such thing.
Now, we can create observables with these functions. In this case what would happen to events and eventData? Since we create an observable based on an event, when the event is triggered, the event data is passed through to observers. So observers are both notified of events triggered and the context/information related to it. These are all happening with observer’s onNext function. However, jQuery uses a wrapper eventData object of HTML DOM EventData object. Despite the difference between these two javascript usages, C# has single type of eventData. Now, let’s create those observers on different platforms and compare them;
Well the reader will probably ask “why such a useful function is not included in the RxJs”. Actually those are in RxJs, but I went through the example above in order to show you and make you understand it’s logic. Instead of doing such additional functions when developing, I recommend that you choose one of the appropriate compatibility libraries; These libraries can work cross-browser. In this case, if you don’t use any libraries in your projects and only work on the pure HTML DOM, using the RxJs-HTML compability library would make you write less code and will also provide Cross-Browser support. In this case, our example application described above will be like this;
The same code by using jQuery and RxJs-jQuery libraries can be written like below;
As you can see, the use of Rx and RxJs libraries is almost identical. Many features in the Rx library are also available in the RxJs library. Our next examples were made using only RxJs. In the following example we wanted log the strings written to WikipediaSearch textbox that their lengths are at least 4 characters long. The rest of the strings expected to be ignored. And from now on RxJs-HTML and RxJs-jQuery compatibility libraries will be used:
The publisher object, that publishes strings that are 4 or more characters long, is SearchableTextEnteredEvent. And the subscriber object, that is responsable for logging the strings, is SearchableTextLogger. As a result, we’re subscribing SearchableTextLogger to SearchableTextEnteredEvent.
3. On the way of AutoSuggesting TextBox
As you noticed, our goal is to make a TextBox that searches automatically for text while we’re typing.
All of the above examples are synchronous, which blocks the UI thread. Just like Rx, RxJs also has asynchronous features that can work without blocking the UI thread. If we look at our previous example, when the user is typing more than 4 characters long string, our logger works. What happens if we wanted to send every log to the server in real-time? In this case these transactions will going to make our server to have some hard times. If one person has pressed a key 3 times a second and 10 people are doing the same thing at the same time, our server will have to meet 3 x 10 = 30 ajax requests in a second. Another point of view is service pricing; Suppose that we are writing the UI layer in the same scenario and benefiting from some paid services for text searching. The price expected to pay for 1 person will be multiplied by 3 in a second.
Let’s interpret what we want to do with Reactive Programming logic; According to the RP logic, on a fixed time, there are fixed number of Publishers (Observables) and Subscribers (Observers). You can also imagine Publishers / Subscriber concepts as demand / supply. The problem we described above is that Publisher is heavily occupied by the user constantly pressing the keys on the keyboard: you may think that there is excessive demand, but the problem is that the demands are too fast. Each time the user presses a key, he/she waits for the relevant string to be logged or printed. But at the time when a person is pressing 3 keys in 1 second, does he/she still expect and be able to read the logs in such a short time? It is impossible. That’s why we’re telling the demands are so fast. For this reason, there are two things we can do to solve this; we can reduce the demand speed or we can increase the supply speed. Since demander is a person, the supplier is our server here. Let’s imagine that we decided to speed up our supplier. Then, if we’re paying for some services or servers etc. we have to make quota increases for it and we also have to take precautions against DOS attacks. This means that we should pay more for the hosting & services (it can be accepted for real-time applications). On the other hand, we can decide to reduce the speed of demands too. In this case, it is usually a more rational solution to tie up the demand.
In Rx libraries, the speed of Demands (aka EventSource, Observable) can be reduced in a variety of ways. For example, Reducing the amount of demand will also reduce the speed of demand. So we’re able to decrease demand by using “where” functions, as in the previous example. In this case I suggest you to use the “distinct” and “distinctUntilChanged” functions.
Notes
“The speed of demand” is not something made up. We can formulize it by
Demand’s Speed= Demand’s Importance / Demand’s Time Period
So, In order to reduce the Demand’s Speed, we can reduce the Demand’s Importance or raise the Demand’s Time Period. Reducing the Demand’s Importance means that we have to tell our users to f*ck off in polite way: “I don’t care wether you make useless demand or not Mr. Client.” :). That’s not an option though. That’s why we have to raise the Demand’s Time Period.
Now let’s see how we can achive this. Suppose a user wants to see the corresponding records in about 1 second after pressing a key. In this case, it will be hold for 1 second after the last key is pressed. And if another key is pressed again during this time, the 1 second countdown will start again. Hurray! We can code this logic in RxJs like this one;
Guess what Rx.Scheduler.timeout.scheduleWithRelative function does? Almost the same thing with our custom code: it just wraps the logic of triggering the observers after specfied delay time via window.setTimeout or window.setInterval functions under the hoods, just like we did.
There are different types of Scheduler objects in RxJs library. For example, when Rx.Scheduler.currentThread is used, user will observe that the cursor in the TextBox and the page freeze for 1 second. The reason is, Rx.Scheduler.currentThread has taken over the process of waiting for 1 second and the feature of this type of scheduler is scheduling on current thread :). So freezing is reasonable. On the other hand, Rx.Scheduler.timeout does all it’s job in a new thread (via window.setTimeout), so it does not cause UI freeze. Finally, Rx.Scheduler.immediate is a scheduler that schedules the process immediately: therefore it’s not suitable for waiting.
throttle function that we created is also exists in RxJs’s Time-Based Operations library. This library contains throttle, delay, timeout, and derivative functions. So the same throttle function we have above is functionally the same with the one in the RxJs library. So, without coding the above custom throttle function, we can also get what we want by just adding the Time-Based Operations library on the page. Now let’s examine how we use the throttle feature;
There is something functionally wrong in here: the same logs are printed repeatedly when the keys such as CapsLock, Ctrl, Alt, Home, End are pressed. In this case, we can reduce these this by adding a filter with “where”, as we did to Observable before, but we need to filter all keyboard codes like this;
The first one uses string filtering with “distinctUntilChanged” function and the second one uses custom key filtering logic with “where”. Please recognize that we are processing the distictUntilChanged operation after the throttle operation. With this approach, it is expected that the latest data will be different from the previous processed data even if it passes the throttle filter.
4. AJAX
One of the most important element in asynchronous operations on client is AJAX. Our goal is to take user input string, send it asynchronously to the service and retrieve the related records. Then we will display these records on the screen. To summarize, we will access a remote data source and process the return values so that the user can see them. AJAX can work asynchronously and asynchronously as you know: if you use jQuery, you’re familiar with the boolean “async” parameter in a usage like $.ajax({…, async: false …}) indicating whether AJAX will be asynchronous or not. Asynchronous use is suitable for our needs.
Reactive programming is quite suitable for push-based (or should I say pull-based? action vs reaction) structures as you know. This includes feeds in social sites or asynchronous data access. In our example, there will be asynchronous data access. The most effective/beneficial use of reactive programming is when a response is asynchronous (not the request): because data only flows asynchronous from server to client this way, otherwise the response comes in one go. Let’s go through on our example; Imagine wrting “hello” in the textbox and after 1 second after pressing the “o” character, we have made a request by sending “hello” to Wikipedia’s related web service. The request will be sent asynchronously to the server and the response will be a list of words for sure. While AJAX is in process and response is not received yet, UI will not be blocked. But in fact the user is blocked already; because, he/she already typed the search criteria and just waiting the search results. For example, if there is a sequence of 100,000 words in the response to the string “hello”, the user have to wait for the complete return, otherwise he/she will not be able to see the records. A large number of returning records is a disadvantage for the user; whereas Wikipedia service is able to send chunks of response (like sending them 10 in one go) it would be a real Reactive programming. This feature is called “XHR Streaming” or “Comet like AJAX”. Please refer to this extremely helpful website in order to understand the possible architecture behind this.
Unfortunately, we are developing a web application that is using it’s services; Not developing Wikipedia’s web services :(. So we can not make changes on service side. For this reason, we will discard the architecture of service side and concentrate on our application along with RxJs.
Almost all of the compatibility packages for RxJs have AJAX support. We will be using RxJs-HTML for this. In this library, “ajax”, “post”, “get”, “getJSON”, “getJSONPRequest” functions are defined for “Rx.Observable” object. These functions make an AJAX request, and return the Observer object. In all of the functions the first parameter is the URL, but the “post” function takes data to send as a second parameter. Whereas the “ajax” function takes more parameter structured by a JSON object such as {url: “www.cronom.com", async: True, method: “get” …}. The example usage is;
Rx.Observable.getJSON(“http://www.cronom.com");
Rx.Observable.ajax({ url: “http://www.cronom.com/", method: “GET”, async: false });We need to use JSONP to make search on Wikipedia service. Normally an AJAX request can not be done to addresses other than the current because the browser is making “Cross Domain” control; if the URL base address that we’re trying to access is not the same as the URL base address of the page that the browser is viewing, the user will see a warning window about this or on some browsers it will fail.


This type of access is by no means impossible accept we’re the owner of the Wikipedia service :); however, using JSONP overcomes this problem. For more detailed information on this topic, I would recommend you to view the following link. We will use JSONP to make search on Wikipedia. Let’s see how we can do this with RxJs;
The thing to note here is the “SearchResultReturnedEvent“ object. I want to draw your attention to the first “select” function call on this;
SearchableTextEnteredEvent
.select(function (text) {
var cleanText = window.encodeURIComponent(text);
var url = 'http://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=' + cleanText + '&callback=JSONPCallback';
return Rx.Observable.getJSONPRequest(url);
}).switchLatest();In order to run JSONP here, we add a parameter like callback=JSONPCallback to the URL. The RxJs-HTML compability library reserved this as a static keyword for JSONP requests, thus it’s required. Finally, the “switchLatest“ function is called: now it’s a little bit complicated. Normally inside the “select” function we have to make an AJAX call and return the response as an array of text. On this scenerio we’re definately not bound to use “Rx.Observable.getJSONPRequest” function; we can do this simply with XMLHttpRequest or even simpler with jQuery.ajax. However our aim is to construct an Observable and we have this functionality on the Observable object returned by the “Rx.Observable.getJSONPRequest” function. In order to stop using the Observable returned by “select” and start using the one returned by “Rx.Observable.getJSONPRequest” we’re using the “switchLatest“ function. So basically we’re switching/replacing the observable dynamically. This is how it goes in Reactive programming: if there is an observable suitable for the job just use it by combining to the filter chain.
And finally; here we go;
5. Results
With RxJs we can benefit from the Observer design pattern. In addition, it gives us great convenience for synchronous and asynchronous operations. I definitely recommend it. The biggest benefit of the RxJs library is related with the HTML 5’s new features of WebSockets and Server-Sent Events (aka EventSource). However, we don’t need them :).
With the comment lines I used in examples and in the code, you can find warnings about some of the errors you may encounter. The Rx library is located directly on Microsoft’s .Net platform. We can use these libraries on smartphones running the Windows OS, but we will not be limited to .Net because we have RxJs; I think the use of WinJS will become very common. RxJs also has WinJS support.
Sample applications and code examples together with their compability libraries are available on Github. You can also find examples of other RxJs libraries that we have not used yet. You don’t have to search for RxJs code samples because the examples in C# language of the Rx library can also guide you; since their use is quite similar.
I hope you liked my article. See you.
References
- http://en.wikipedia.org/wiki/Observer_pattern#Example
- http://www.a-coding.com/2010/10/observer-pattern-in-objective-c.html
- http://www.codeproject.com/Articles/328365/Understanding-and-Implementing-Observer-Pattern-in
- https://github.com/Reactive-Extensions
- http://rx.codeplex.com/
- https://github.com/Reactive-Extensions/RxJS
- https://rxjs.codeplex.com/
- http://msdn.microsoft.com/en-us/data/gg577611
- http://www.debugtheweb.com/test/teststreaming.aspx
- http://en.wikipedia.org/wiki/JSONP
