Discovery – a HTML and JavaScript example

I value ease of understanding in code. I find it helps me to develop more maintainable software that I am confident to change. One of the things that I attempt to optimise is how easy it is to discover how the code works. I ran into an example of this is in a code review recently that I thought was worth sharing. Below is a modified example of what I was reviewing.

The example

Assume the following HTML.

  
  <textarea name=’area1’ id=’area1’ class=’area-class’></textarea>
  <textarea name=’area2’ id=’area2’ class=’area-class’></textarea>
  <textarea name=’area3’ id=’area3’ class=’area-class’></textarea>
  

Along with the following JavaScript in a .js file that is loaded with the HTML page.

  
  function update_counter() {
    // some code to update the element
  }

  $(“#area1”).change( update_counter );
  $(“#area2”).change( update_counter );
  $(“#area3”).change( update_counter );
  

How does the next developer know that there is a counter being hooked up? How does the next developer know how it is being hooked up? How easily could a developer look at the HTML and successfully add a new textarea with the same capabilities?

Based on the above HTML alone, there is no clue that there is a JavaScript hook into it. There may be a JavaScript include in the HTML page that will lead us to the file that is doing the work, but that isn’t something that will be looked at unless there is a reason to look and the HTML isn’t giving a reason to look.

Knowing which file to look at could be even less obvious if you’re using something like the Rails asset pipeline that precompiles and bundles files together as there is unlikely to be a single include for the .js file.

If we knew we were looking for some JavaScript, another discoverability mechanism would be to search for any instance of the textarea’s id or class being used in JavaScript. This could be a little painful.

A simple fix

In this case, a simple fix is to move the initialiser that hooks the update_counter to the specific DOM elements to be coded on the HTML page itself. This highlights to a developer what DOM elements are being bound to JavaScript in the same file as the elements are being defined. This provides a breadcrumb for the developer to follow in order to discover how things are hooked up.

When I have used KnockOut.js in the past, I have had the binding action run on the HTML page to bind the HTML to the relevant JavaScript model to help allow discovery of what JavaScript code to look for.

What if it isn’t that simple

What if the code that is being run to do the binding is a lot more complex?

Another way to do this could be with data- attributes.

  
  <textarea data-counter name=’area1’ id=’area1’ class=’area-class’></textarea>
  <textarea data-counter name=’area2’ id=’area2’ class=’area-class’></textarea>
  <textarea data-counter name=’area3’ id=’area3’ class=’area-class’></textarea>
  

and the Javascript binding becomes

  
  $(“[data-counter]”).change( update_counter );
  

This code now allows the developer to look at the mark up and ask the question “What does the data-counter attribute do?” This will lead them to the fact that there is JavaScript binding to the element.

Even if the developer does not take any notice of the data-counter attribute, copying a row and updating the id to a unique area id and name will still work the same as all the other textareas without the developer needing to think.

The term “Falling into the Pit of Success” is sometimes used to represent things that developers will do by default that will in fact be the correct decision. This is an example of that.

The additional benefit is that the data-counter could be used on multiple pages across the site and it will work the same.

The actual instance

In this case, the counter is visually obvious, so there are some clues for the developer to try to look for the JavaScript counter and how it ties in. However the actual instance that I was code reviewing was saving something to local storage per textarea, and then putting it back, in order to implement a feature. This was even more opaque as it was less obvious it was happening or why.

Value discoverability

Always think about how the next person will discover how the code you are writing now fits together. It might even be you in 6 months time. How quickly can it be worked out? Is it explicit and obvious and easy to do the right thing? How will they discover what you did?

The faster it is to discover the way the code works, the less time will be wasted trying to find it out how it works and the more effective you and your team can be.

Advertisements

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s