Step by Step implementing Two-Way Data Binding in Vanilla JavaScript

Data Binding is one of the most important features of all the frameworks. It ensures that the data model and the views are in sync with each other. It is very fundamental feature of any MV* frameworks such that Model-View-Controller, Mode-View-ViewModel, and Model-View-Presenter, etc.

Popular JavaScript based frameworks such that React, Angular have their way to implement it. However, it is a good idea to know how a basic two-way data binding can be implemented using vanilla JavaScript.  That would give you an overview of how much heavy lifting is done by the framework when you use features like data binding.

To get most of this post, you should have a basic understanding of following JavaScript features

  • Creating an object as literal
  • Adding a property with Object.defineProperty
  • Using setter and getter
  • forEach statement

 

You can refresh about JavaScript object creation in this video on geek97. Let us get started,

On the HTML, we have put one input text box and two span elements.  Whenever the user enters a value in the text box, data in <span> element should get updated.

We are going to write JavaScript for data binding in the databinding.js file, so we also added a reference to that in the HTML.

To start with databinding.js file contains an Immediately Invoked Function Expression (IIFE). We write all the codes inside this function,

At this point, on launching the application, you should get below output. Right now, if you enter anything in the Name field nothing would be affected.

cd1

Note: If you are using Visual Studio Code, install the extension Live Server, and run the HTML in the browser, right click on the file and from the context menu select “Open with Live Server” to launch the application.

Our first task is to select all the elements which have [data-geek97-bind] attribute set, and also check for their type. Right now, as we are creating binding only for input type text, so we can make a selection of elements and type checking as shown below,

We have created an empty object called dbrepo, which would maintain the state between the data bound elements. The dbrepo object would make sure that all DOM elements with [data-geek97-bind] attribute set to value ‘name’ is in sync and have the same value.

To achieve that, what all we need to do is to add a property dynamically to the dbrepo object for each unique value of [data-geek97-bind] attribute in the DOM elements. For that, let us create a function called addToScope. In the function, we check whether a particular property exists or not, if not then using the Object.defineProperty() method adds a property to the dbrepo object.

Using the hasOwnProperty() method, determining whether property already exists or not, if not then add it using the Object.defineProperty() method. You can learn more about property descriptor and Object.defineProperty() here

We need to do some work in the setter function.

  • First, find all the elements with data-geek97-bind attribute set to the same value.
  • If the element type is text, set its value, otherwise set innerHtml of the element

Above two tasks can be performed in the setter function as below,

Putting everything together, code to perform two-way data binding is as below:

If you want to change the value in the code by just rewriting the value of the property in the dbrepo object,

At this point, on launching the application you should get below output. Right now, if you enter anything in the Name field, the other two spans would be affected.

cd2

Still, there is scope for much improvement in this code,

  1. Instead of rewriting the innerHtml, append the next text
  2. Extend it for other types than text.

I hope you find this post useful. Thanks for reading.

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s