Tag Archives: frp

A simple html/js binding system using Reactive Programming with ProAct.js

Yeah! We are going to talk about Reactive Programming, even doing something with it!!!

So I’m proud to announce that ProAct.js – my RP implementation is production-ready. At the time of this post the most recent version is 1.2.1

So… What is Reactive Programming -> it is programming based on the data flow. To put it simple, everything is data, users read data, create data, update data, delete data, your system deals with it in some way. Using The Reactive Paradigm we just say in a declarative way, which part of the data depends on which and the program deals with changes (data flow) by itself. It’s a kind of magic!

And what is ProAct.js?
It is implementation of this Reactive Way in JavaScript, using both object oriented and functional approaches – you’ll see.

We are going to implement Html bindings using ProAct.js and jQuery/zepto. We can do it without jQuery/zepto but it is easier that way.
We are going to use two of the features ProAct.js gives us. The first one is Reactive Objects – these are normal JavaScript objects but with magical fields that can depend on one-another called ‘Properties’ (The ‘Pro’ from ProAct.js comes from them).

Here is an example:

var obj = ProAct.prob({
 x: 4,
 y: 5,
 z: function () {
   return this.x + this.y;
 }
});
// obj.z is not a function any more it is a magical field!
console.log(obj.z); // 9 (4 + 5)
obj.x = 10;
console.log(obj.z); // 15 (10 + 5)
obj.y = 15;
console.log(obj.z); // 25 (10 + 15)

The other feature is the FRP Streams. The example with streams will use our bindings.

Let’s begin!
The code for the bindings with example how to use them is in this fiddle.
Our main purpose is to create a ProAct.Bindings namespace, containing the logic. So everything will go in a module like this:

(function (window, ProAct, $) {
 'use strict';
})(window, ProAct, $);

Our main function that we’ll export is ‘ProAct.Bindings.create($el, context)’. We define it like that:

 function create($el, obj) {
   var $bindings = $el.find('[pro-bind]').add($el.filter('[pro-bind]')); // 1

   $bindings.each(function () {
     setupBinding($(this), obj); // 2
   });
 }

 ProAct.Bindings = {
   create: create
 };

We are going to use a context object, containing the bound fields and tags with attributes ‘pro-bind='<field>’.
So for example if we want to bind obj.z from the Reactive Objects example to a span tag’s content, the tag will look like like that:
‘<span class=”test” pro-bind=”z”></span>’
and we are going to call our main function like that:
ProAct.Bindings.create($(‘.test’), obj);
And voila – changing obj.z will update the html. At least if we implement it!

What does ‘create‘ do?
1. It queries all the children of the passed element that have ‘pro-bind’ attribute and the element itself, if it has the attribute.
For every element queried it
2. calls ‘setupBinding’ with the element and the context object.

Let’s define setupBinding:

 function setupBinding($binding, obj) {
   var property = $binding.attr('pro-bind'); // 1

   if (!obj.p(property)) {
     return; // 2
   }

   onProp($binding, obj, property); // 3
 }

This function
1. gets the value of the ‘pro-bind’ attribute. This is the name of the context’s field.
2. if there is no such field in the context it does nothing,
3. if there is – it calls another function ‘onProp’ with the bound element, the context and the name of the field.
We use the special ‘p’ function of the Reactive Objects here to check if given Property exists. More on that in another post.

We continue, defining ‘onProp’:

 function onProp($binding, obj, property, safe) {
   var tag = $binding.prop('tagName').toLowerCase(); // 1

   obj.p(property).on(function () { // 2
     if (tag === 'input') { // 3
       $binding.prop('value', obj[property]);
     } else {
       $binding.text(obj[property]);
     }
   });

   obj.p(property).update(); // 4
 }

Here we define the actual binding between the property of the context object and the html.
1. First we get the tag of the html element.
2. Using the ‘p‘ method of the Reactive context we get the actual Property representing the field to bind and add a listener to its changes.
3. When the Property changes we update the html element. If the tag is input we update its value, otherwise we update the text content of the element.
4. We call ‘update’ on the Property representing the bound field to sync its value to the html content.

This is it. Now we can write html like this:

 <div class="sum">
   <p>The result of <span pro-bind="x"></span> + <span pro-bind="y"></span> is <span pro-bind="z"></span>
  </p>
</div>

And bind object to it like this:

var sum = ProAct.prob({
 x: 4,
 y: 5,
 z: function () {
   return this.x + this.y;
 }
});

ProAct.Bindings.create($('.sum'), sum);

Changing sum’s x, or y will update the html.
But how to change x and y using input tags? We will use the second feature, I mentioned – the FRP streams:

function intVal(e) { // 1
 var val = parseInt(e.target.value, 10);

 return isNaN(val) ? 0 : val;
}

var xStream = new ProAct.Stream(); // 2
var yStream = new ProAct.Stream();

sum.p('x').into(xStream.map(intVal)); // 3
sum.p('y').into(yStream.map(intVal));

window.App = { // 4
 x: xStream,
 y: yStream
};

1. First we will define a mapping function that maps a ‘key up’ event to the value of the input tag, it comes from.
2. Second we create two ProAct.Streams -> one for the sum’s x field and on for the y field.
3. Here we do FRP magic -> on every stream we map the mapping function, so if ‘key up’ event enters the stream, it will be transformed to the value of its input tag. And what comes from the streams goes to the value of the corresponding sum’s Property. (This is magic but I’m going to write posts/docs explaining what’s happening).
4. We export the two streams to be easy to use them in the html.

And this is the html:

<input name="x" type="text" onkeyup="App.x.trigger(event)" pro-bind="x" />
<input name="y" type="text" onkeyup="App.y.trigger(event)" pro-bind="y" />

So on keyup event we trigger the event into the streams, it is transformed to the value of its target input tag and the right Property’s value is set to this value.

This is it. We have actual, working bindings. The example from the fiddle is a bit more complex and you can play with it.

I’m sorry if the examples in this post feel a bit magical, but the idea is to show you just how powerful ProAct.js is and what you can do with it, not how it works.
If you’re interested, it has some API documentation.

Useful Links:

  1. ProAct.js – http://proactjs.github.io
  2. Bacon.js FRP implementation more rich and powerful than the current ProAct.js one – http://baconjs.github.io
  3. Kefir.js – Another FRP implementation – http://pozadi.github.io/kefir