Categories: Web Dev Training

Reactive Programming with JavaScript, Ruby and Python

Reactive programming is a concept that is finally gaining some popularity among programmers. It makes it easier to think in data flows and to manage and work with them. Instead of imperative programming, you’re thinking about code as a series of processes that take place on streams.

This is similar to the conceptual shift to map/reduce thinking. But it takes those ideas further. You’re doing a map/reduce and then connecting the data to other filters and maps and creating multiple pipelines so that the right data gets to the right place.

For example, when a user clicks a button in a web app (or desktop app), that click event can be propagated through the system to all the subscribers that are listening and waiting for that event.

When working with the Angular frontend web framework, that latest versions are now using RxJS, the reactive programming library for JavaScript. It is the underlying framework for working with events. Previously in AngularJS 1.x you would use the broadcast and emit system to act on events.

Reactive Programming

With Reactive, you have a generalized library for working with observables and subscribers which can work well with other libraries and other JavaScript code.

In Ruby and Python, other concepts have held sway for a long time, so here are some examples on how to do reactive programming Ruby and how to do reactive programming in Python.

These are basic examples of filtering and creating observables, think of them as the equivalent of “Hello World”..

You can find a list of other languages that are supported with a reactive library on the ReactiveX website.

RxJS: JavaScript Example

Let’s begin by creating an observable:

var numbers = [1,2,3,4,5];
var all = Rx.Observable.from(numbers);

This observable is being created from a list of numbers. It’s possible to convert other types of lists into Observables.

Next we want to print out all of the numbers. We do this by subscribing to the observable with a function:

all.subscribe(function(number) {
console.log("The number is " + number);
});

Right now this looks like a for loop, but remember that observables are meant for events in time. There could be milliseconds or seconds or minutes between each event that the observable is emitting to the subscriber.

Next, let’s create a new flow of data by filtering all of the numbers so we only receive even numbers in our subscriber:

var only_evens = all.filter(function(number) {
return number % 2 === 0;
});

Again we print out the numbers and you will notice that we only print out even numbers:

only_evens.subscribe(function(number) {
console.log("This number is even: " + number);
});

That was a simple example of creating two flows; one with all values, and a filtered flow of values.

Now imagine in your next web app, a user does any action. That action is sent through an observable and we can have a subscriber that waits for a specific button click action or subscribes to any button click.

Then imagine a 3rd party API or REST API whose response you’re waiting on, you are subscribing to the observable and filtering for certain responses straight for display in your user interface.

There is a lot of power in reactive programming and it makes diagramming the process of UI event flow much easier. Each new user interaction or display is just another flow of events to be filtered and subscribed to.

RxRuby: Ruby Example

Now let’s do the same thing but this time in Ruby with RxRuby.

First we create the observable and print out all the numbers:

require 'rx_ruby'
numbers = [1, 2, 3, 4, 5]
all = RxRuby::Observable.from_array numbers
all.subscribe do |number|
puts "The number is #{number}"
end

Then we filter the observable and print out the filtered values:

only_evens = all.select(&:even?)
only_evens.subscribe do |number|
puts "This number is even: #{number}"
end

One interesting note when creating your observable, you should use from_array because simply using from will only emit the flow of values once. I’m not sure why RxRuby has this particular behaviour.

RxPy: Python Example

And now let’s do it all over again but with Python and RxPy.

We create the observable with all values and print them out:

import rx
numbers = [1, 2, 3, 4, 5]
all = rx.Observable.from_(numbers)
all.subscribe(lambda number: print('The number is {}'.format(number)))

And again we filter the observable’s values to a subset and print those out as well:

only_evens = all.filter(lambda number: number % 2 == 0)
only_evens.subscribe(
lambda number: print('This number is even: {}'.format(number)))

Please note that in the JavaScript example we used the operator “filter” and in the Python example. But in the Ruby example we used “select”. If you try and use “select” in the Python example you will get a list of boolean values instead of properly filtering the list. There are a few differences like this between each library.

Conclusion

This was a short introduction into reactive programming. There’s a lot more you can do and here I wanted to demonstrate that it’s possible to use Rx with more than just JavaScript. I’ve only seen it used in Java and JavaScript and thought it was time to write more examples of Ruby and Python so others can see that those languages can also benefit from Rx and Reactive programming.

Rudolf Olah is a software development expert with over 8 years of professional software developer experience. He has produced the video courses "Reactive Programming in Python with RxPy, PyQt5 and Tornado" and "Learning AngularJS Testing" for PacktPublishing. Rudolf offers web development training courses for individual developers and for web development teams. He writes about tech leadership, career coaching and project management.