Tag Archives: javascript

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

Inheritance in JavaScript – A Cool Way

So, JavaScript is a strange language. This prototyping stuff is new for everyone coming from another ecosystem. But it’s not so complex. There are many libraries that provide extending ‘class‘ methods that mimic extending from more conventional languages, like Java for example. (Example of such method is Ember’s Ember.Object.extend)

Now I’m going to show you how to write such an inheritance method in JavaScript and how to use it. In the meantime we will see how prototyping works.

Let’s begin.

First of all we will define a helper method used to copy the properties from one object to another, overriding the common ones:


function ex (destination, source) {
  var p;

  for (p in source) {
    if (source.hasOwnProperty(p)) {
      destination[p] = source[p];
    }
  }
  return destination;
}

Here we just copy the own properties (not the inherited/prototype ones) from the source object to the destination object. Read more about hasOwnProperty here.

Let’s define our main extending method:


function extend (data, staticData) {
  var parent = this, // 1
      child = function () { // 2
        if (data.initialize) { // 2.1
          data.initialize.apply(this, arguments);
        } else { // 2.2
          parent.apply(this, arguments);
        }
      };

  ex(child, parent); // 3
    
  if (staticData) { // 4
    ex(child, staticData);
  }

  if (!data) { // 5
    data = {};
  }

  child.prototype = ex(Object.create(parent.prototype), data); // 6
  child.prototype.constructor = child; // 7
  child.prototype.__super = parent.prototype; // 8

  return child; // 9
}

The idea is that this method is called on the class to become parent class (you will see in the next example what I am talking about).
It has two parameters – data and staticData.
The data parameter is used to pass instance fields and methods to the child class that may override parent ones.
The staticData is used to define class level fields and methods to the child class.
Let’s see what we are doing:

  1. The parent class is this – the caller of the method.
  2. The child class is defined with a new constructor.
    2.1. If we pass an ‘initialize‘ method as field of the data parameter it is used for the       initialization. So in our inheritance ‘initialize‘ is the constructor method.
    2.2. If not we call the parent’s constructor as super constructor.
  3. We use the previously defined ‘ex‘ function to copy all the parent’s static methods/fields in the child – this includes the ‘extend‘ method as well, so the child can become a parent class too.
  4. If we passed staticData, we copy it to the child class – that way we can override some of the previously copied parent static methods/fields.
  5. If we didn’t pass ‘data‘ parameter assign to it default value – the empty object.
  6. Now it is time for the instance methods and fields – create the child prototype, using the parent’s prototype modified with the passed data.
  7. Set the constructor to the child’s prototype.
  8. Set a pointer to the parent’s prototype – a __super.
  9. OK, the child class is ready – return it.

What are we really doing?
First of all, classes in JavaScript are defined using functions – constructors. Every function can be a constructor. If you call the function preceding it with the new keyword, it creates an instance.
In the constructor, when called with ‘new‘, ‘this‘ points to the instance to be created – so if we define fields or methods on ‘this‘ they become instance ones.

When we have an instance and we call method or read field and it is not found in ‘this‘, it is searched in the prototype object of the constructor of the instance.
So if we define methods or fields in the object, pointed by the prototype field of the constructor function – they become instance ones too.

That’s why copying the parent prototype into the child’s is basically extending the parent into the child.

That’s all – I’m doing all of this in the ‘extend‘ method. Let’s use it!


function Foo (a, b) {//1
  this.a = a;
  this.b = b;
}

Foo.prototype.c = function () {//2
  return this.a + this.b
};

var foo = new Foo(2, 5);//3
console.log(foo.c());//4
  1. We create a new function (class); We assign the passed ‘a‘ and ‘b‘ parameters to this.
  2. We are adding a new instance function ‘c‘ (In the prototype of Foo). It calculates the sum of ‘this.a‘ and ‘this.b‘.
  3. We create a new instance!
  4. The result will be 2+5=7

Now is time for the inheritance!


Foo.extend = extend; //1

Bar = Foo.extend({ //2
  initialize: function (a, b, d) {
    this.__super.constructor(a, b);
    this.d = d;
  },    
  d: 8,
  e: function () {
    return this.a + this.b + this.d;
  }
});

var bar = new Bar(3, 1, 9); //3
console.log(bar.c(), bar.e()); //4
  1. We set the ‘extend‘ function to Foo. Now Foo can be parent class!
  2. We extend Foo passing data with:
    – ‘initialize‘ method (remember – this is your constructor), that calls the super constructor (Foo) with the passed ‘a‘ and ‘b‘ parameters and sets ‘d‘ in ‘this‘.
    – ‘d’ – a new instance field.
    – ‘e‘ – a new instance method, calculating the sum of ‘this.a‘, ‘this.b‘ and ‘this.c‘.
  3. Let’s create a new Bar instance!
  4. We’ll see 3+1=4 and 3+1+9=13

So we have a child class now? Very similar to Ruby or Java isn’t it. We can extend Bar too, it has the ‘extend‘ method inherited from Foo. You can try that in this jsfiddle.

OK that’s it.

Useful Links:

  1. MDN  Javascript – https://developer.mozilla.org/en/docs/Web/JavaScript
  2. Ideas in coder wall – https://coderwall.com/p/ajugeq