Skip navigation
Help

Rebecca Murphey

warning: Creating default object from empty value in /var/www/vhosts/sayforward.com/subdomains/recorder/httpdocs/modules/taxonomy/taxonomy.pages.inc on line 33.
Original author: 
(author unknown)

We’ve all been there: that bit of JavaScript functionality that started out as just a handful of lines grows to a dozen, then two dozen, then more. Along the way, a function picks up a few more arguments; a conditional picks up a few more conditions. And then one day, the bug report comes in: something’s broken, and it’s up to us to untangle the mess.

As we ask our client-side code to take on more and more responsibilities—indeed, whole applications are living largely in the browser these days—two things are becoming clear. One, we can’t just point and click our way through testing that things are working as we expect; automated tests are key to having confidence in our code. Two, we’re probably going to have to change how we write our code in order to make it possible to write tests.

Really, we need to change how we code? Yes—because even if we know that automated tests are a good thing, most of us are probably only able to write integration tests right now. Integration tests are valuable because they focus on how the pieces of an application work together, but what they don’t do is tell us whether individual units of functionality are behaving as expected.

That’s where unit testing comes in. And we’ll have a very hard time writing unit tests until we start writing testable JavaScript.

Unit vs. integration: what’s the difference?

Writing integration tests is usually fairly straightforward: we simply write code that describes how a user interacts with our app, and what the user should expect to see as she does. Selenium is a popular tool for automating browsers. Capybara for Ruby makes it easy to talk to Selenium, and there are plenty of tools for other languages, too.

Here’s an integration test for a portion of a search app:

def test_search
  fill_in('q', :with => 'cat')
  find('.btn').click
  assert( find('#results li').has_content?('cat'), 'Search results are shown' )
  assert( page.has_no_selector?('#results li.no-results'), 'No results is not shown' )
end

Whereas an integration test is interested in a user’s interaction with an app, a unit test is narrowly focused on a small piece of code:

When I call a function with a certain input, do I receive the expected output?

Apps that are written in a traditional procedural style can be very difficult to unit test—and difficult to maintain, debug, and extend, too. But if we write our code with our future unit testing needs in mind, we will not only find that writing the tests becomes more straightforward than we might have expected, but also that we’ll simply write better code, too.

To see what I’m talking about, let’s take a look at a simple search app:

Srchr

When a user enters a search term, the app sends an XHR to the server for the corresponding data. When the server responds with the data, formatted as JSON, the app takes that data and displays it on the page, using client-side templating. A user can click on a search result to indicate that he “likes” it; when this happens, the name of the person he liked is added to the “Liked” list on the right-hand side.

A “traditional” JavaScript implementation of this app might look like this:

var tmplCache = {};

function loadTemplate (name) {
  if (!tmplCache[name]) {
    tmplCache[name] = $.get('/templates/' + name);
  }
  return tmplCache[name];
}

$(function () {

  var resultsList = $('#results');
  var liked = $('#liked');
  var pending = false;

  $('#searchForm').on('submit', function (e) {
    e.preventDefault();

    if (pending) { return; }

    var form = $(this);
    var query = $.trim( form.find('input[name="q"]').val() );

    if (!query) { return; }

    pending = true;

    $.ajax('/data/search.json', {
      data : { q: query },
      dataType : 'json',
      success : function (data) {
        loadTemplate('people-detailed.tmpl').then(function (t) {
          var tmpl = _.template(t);
          resultsList.html( tmpl({ people : data.results }) );
          pending = false;
        });
      }
    });

    $('<li>', {
      'class' : 'pending',
      html : 'Searching &hellip;'
    }).appendTo( resultsList.empty() );
  });

  resultsList.on('click', '.like', function (e) {
    e.preventDefault();
    var name = $(this).closest('li').find('h2').text();
    liked.find('.no-results').remove();
    $('<li>', { text: name }).appendTo(liked);
  });

});

My friend Adam Sontag calls this Choose Your Own Adventure code—on any given line, we might be dealing with presentation, or data, or user interaction, or application state. Who knows! It’s easy enough to write integration tests for this kind of code, but it’s hard to test individual units of functionality.

What makes it hard? Four things:

  • A general lack of structure; almost everything happens in a $(document).ready() callback, and then in anonymous functions that can’t be tested because they aren’t exposed.
  • Complex functions; if a function is more than 10 lines, like the submit handler, it’s highly likely that it’s doing too much.
  • Hidden or shared state; for example, since pending is in a closure, there’s no way to test whether the pending state is set correctly.
  • Tight coupling; for example, a $.ajax success handler shouldn’t need direct access to the DOM.

Organizing our code

The first step toward solving this is to take a less tangled approach to our code, breaking it up into a few different areas of responsibility:

  • Presentation and interaction
  • Data management and persistence
  • Overall application state
  • Setup and glue code to make the pieces work together

In the “traditional” implementation shown above, these four categories are intermingled—on one line we’re dealing with presentation, and two lines later we might be communicating with the server.

Code Lines

While we can absolutely write integration tests for this code—and we should!—writing unit tests for it is pretty difficult. In our functional tests, we can make assertions such as “when a user searches for something, she should see the appropriate results,” but we can’t get much more specific. If something goes wrong, we’ll have to track down exactly where it went wrong, and our functional tests won’t help much with that.

If we rethink how we write our code, though, we can write unit tests that will give us better insight into where things went wrong, and also help us end up with code that’s easier to reuse, maintain, and extend.

Our new code will follow a few guiding principles:

  • Represent each distinct piece of behavior as a separate object that falls into one of the four areas of responsibility and doesn’t need to know about other objects. This will help us avoid creating tangled code.
  • Support configurability, rather than hard-coding things. This will prevent us from replicating our entire HTML environment in order to write our tests.
  • Keep our objects’ methods simple and brief. This will help us keep our tests simple and our code easy to read.
  • Use constructor functions to create instances of objects. This will make it possible to create “clean” copies of each piece of code for the sake of testing.

To start with, we need to figure out how we’ll break our application into different pieces. We’ll have three pieces dedicated to presentation and interaction: the Search Form, the Search Results, and the Likes Box.

Application Views

We’ll also have a piece dedicated to fetching data from the server and a piece dedicated to gluing everything together.

Let’s start by looking at one of the simplest pieces of our application: the Likes Box. In the original version of the app, this code was responsible for updating the Likes Box:

var liked = $('#liked');

var resultsList = $('#results');


// ...


resultsList.on('click', '.like', function (e) {
  e.preventDefault();

  var name = $(this).closest('li').find('h2').text();

  liked.find( '.no-results' ).remove();

  $('<li>', { text: name }).appendTo(liked);

});

The Search Results piece is completely intertwined with the Likes Box piece and needs to know a lot about its markup. A much better and more testable approach would be to create a Likes Box object that’s responsible for manipulating the DOM related to the Likes Box:

var Likes = function (el) {
  this.el = $(el);
  return this;
};

Likes.prototype.add = function (name) {
  this.el.find('.no-results').remove();
  $('<li>', { text: name }).appendTo(this.el);
};

This code provides a constructor function that creates a new instance of a Likes Box. The instance that’s created has an .add() method, which we can use to add new results. We can write a couple of tests to prove that it works:

var ul;

setup(function(){
  ul = $('<ul><li class="no-results"></li></ul>');
});

test('constructor', function () {
  var l = new Likes(ul);
  assert(l);
});

test('adding a name', function () {
  var l = new Likes(ul);
  l.add('Brendan Eich');

  assert.equal(ul.find('li').length, 1);
  assert.equal(ul.find('li').first().html(), 'Brendan Eich');
  assert.equal(ul.find('li.no-results').length, 0);
});

Not so hard, is it? Here we’re using Mocha as the test framework, and Chai as the assertion library. Mocha provides the test and setup functions; Chai provides assert. There are plenty of other test frameworks and assertion libraries to choose from, but for the sake of an introduction, I find these two work well. You should find the one that works best for you and your project—aside from Mocha, QUnit is popular, and Intern is a new framework that shows a lot of promise.

Our test code starts out by creating an element that we’ll use as the container for our Likes Box. Then, it runs two tests: one is a sanity check to make sure we can make a Likes Box; the other is a test to ensure that our .add() method has the desired effect. With these tests in place, we can safely refactor the code for our Likes Box, and be confident that we’ll know if we break anything.

Our new application code can now look like this:

var liked = new Likes('#liked');
var resultsList = $('#results');



// ...



resultsList.on('click', '.like', function (e) {
  e.preventDefault();

  var name = $(this).closest('li').find('h2').text();

  liked.add(name);
});

The Search Results piece is more complex than the Likes Box, but let’s take a stab at refactoring that, too. Just as we created an .add() method on the Likes Box, we also want to create methods for interacting with the Search Results. We’ll want a way to add new results, as well as a way to “broadcast” to the rest of the app when things happen within the Search Results—for example, when someone likes a result.

var SearchResults = function (el) {
  this.el = $(el);
  this.el.on( 'click', '.btn.like', _.bind(this._handleClick, this) );
};

SearchResults.prototype.setResults = function (results) {
  var templateRequest = $.get('people-detailed.tmpl');
  templateRequest.then( _.bind(this._populate, this, results) );
};

SearchResults.prototype._handleClick = function (evt) {
  var name = $(evt.target).closest('li.result').attr('data-name');
  $(document).trigger('like', [ name ]);
};

SearchResults.prototype._populate = function (results, tmpl) {
  var html = _.template(tmpl, { people: results });
  this.el.html(html);
};

Now, our old app code for managing the interaction between Search Results and the Likes Box could look like this:

var liked = new Likes('#liked');
var resultsList = new SearchResults('#results');


// ...


$(document).on('like', function (evt, name) {
  liked.add(name);
})

It’s much simpler and less entangled, because we’re using the document as a global message bus, and passing messages through it so individual components don’t need to know about each other. (Note that in a real app, we’d use something like Backbone or the RSVP library to manage events. We’re just triggering on document to keep things simple here.) We’re also hiding all the dirty work—such as finding the name of the person who was liked—inside the Search Results object, rather than having it muddy up our application code. The best part: we can now write tests to prove that our Search Results object works as we expect:

var ul;
var data = [ /* fake data here */ ];

setup(function () {
  ul = $('<ul><li class="no-results"></li></ul>');
});

test('constructor', function () {
  var sr = new SearchResults(ul);
  assert(sr);
});

test('display received results', function () {
  var sr = new SearchResults(ul);
  sr.setResults(data);

  assert.equal(ul.find('.no-results').length, 0);
  assert.equal(ul.find('li.result').length, data.length);
  assert.equal(
    ul.find('li.result').first().attr('data-name'),
    data[0].name
  );
});

test('announce likes', function() {
  var sr = new SearchResults(ul);
  var flag;
  var spy = function () {
    flag = [].slice.call(arguments);
  };

  sr.setResults(data);
  $(document).on('like', spy);

  ul.find('li').first().find('.like.btn').click();

  assert(flag, 'event handler called');
  assert.equal(flag[1], data[0].name, 'event handler receives data' );
});

The interaction with the server is another interesting piece to consider. The original code included a direct $.ajax() request, and the callback interacted directly with the DOM:

$.ajax('/data/search.json', {
  data : { q: query },
  dataType : 'json',
  success : function( data ) {
    loadTemplate('people-detailed.tmpl').then(function(t) {
      var tmpl = _.template( t );
      resultsList.html( tmpl({ people : data.results }) );
      pending = false;
    });
  }
});

Again, this is difficult to write a unit test for, because so many different things are happening in just a few lines of code. We can restructure the data portion of our application as an object of its own:

var SearchData = function () { };

SearchData.prototype.fetch = function (query) {
  var dfd;

  if (!query) {
    dfd = $.Deferred();
    dfd.resolve([]);
    return dfd.promise();
  }

  return $.ajax( '/data/search.json', {
    data : { q: query },
    dataType : 'json'
  }).pipe(function( resp ) {
    return resp.results;
  });
};

Now, we can change our code for getting the results onto the page:

var resultsList = new SearchResults('#results');

var searchData = new SearchData();

// ...

searchData.fetch(query).then(resultsList.setResults);

Again, we’ve dramatically simplified our application code, and isolated the complexity within the Search Data object, rather than having it live in our main application code. We’ve also made our search interface testable, though there are a couple caveats to bear in mind when testing code that interacts with the server.

The first is that we don’t want to actually interact with the server—to do so would be to reenter the world of integration tests, and because we’re responsible developers, we already have tests that ensure the server does the right thing, right? Instead, we want to “mock” the interaction with the server, which we can do using the Sinon library. The second caveat is that we should also test non-ideal paths, such as an empty query.

test('constructor', function () {
  var sd = new SearchData();
  assert(sd);
});

suite('fetch', function () {
  var xhr, requests;

  setup(function () {
    requests = [];
    xhr = sinon.useFakeXMLHttpRequest();
    xhr.onCreate = function (req) {
      requests.push(req);
    };
  });

  teardown(function () {
    xhr.restore();
  });

  test('fetches from correct URL', function () {
    var sd = new SearchData();
    sd.fetch('cat');

    assert.equal(requests[0].url, '/data/search.json?q=cat');
  });

  test('returns a promise', function () {
    var sd = new SearchData();
    var req = sd.fetch('cat');

    assert.isFunction(req.then);
  });

  test('no request if no query', function () {
    var sd = new SearchData();
    var req = sd.fetch();
    assert.equal(requests.length, 0);
  });

  test('return a promise even if no query', function () {
    var sd = new SearchData();
    var req = sd.fetch();

    assert.isFunction( req.then );
  });

  test('no query promise resolves with empty array', function () {
    var sd = new SearchData();
    var req = sd.fetch();
    var spy = sinon.spy();

    req.then(spy);

    assert.deepEqual(spy.args[0][0], []);
  });

  test('returns contents of results property of the response', function () {
    var sd = new SearchData();
    var req = sd.fetch('cat');
    var spy = sinon.spy();

    requests[0].respond(
      200, { 'Content-type': 'text/json' },
      JSON.stringify({ results: [ 1, 2, 3 ] })
    );

    req.then(spy);

    assert.deepEqual(spy.args[0][0], [ 1, 2, 3 ]);
  });
});

For the sake of brevity, I’ve left out the refactoring of the Search Form, and also simplified some of the other refactorings and tests, but you can see a finished version of the app here if you’re interested.

When we’re done rewriting our application using testable JavaScript patterns, we end up with something much cleaner than what we started with:

$(function() {
  var pending = false;

  var searchForm = new SearchForm('#searchForm');
  var searchResults = new SearchResults('#results');
  var likes = new Likes('#liked');
  var searchData = new SearchData();

  $(document).on('search', function (event, query) {
    if (pending) { return; }

    pending = true;

    searchData.fetch(query).then(function (results) {
      searchResults.setResults(results);
      pending = false;
    });

    searchResults.pending();
  });

  $(document).on('like', function (evt, name) {
    likes.add(name);
  });
});

Even more important than our much cleaner application code, though, is the fact that we end up with a codebase that is thoroughly tested. That means we can safely refactor it and add to it without the fear of breaking things. We can even write new tests as we find new issues, and then write the code that makes those tests pass.

Testing makes life easier in the long run

It’s easy to look at all of this and say, “Wait, you want me to write more code to do the same job?”

The thing is, there are a few inescapable facts of life about Making Things On The Internet. You will spend time designing an approach to a problem. You will test your solution, whether by clicking around in a browser, writing automated tests, or—shudder—letting your users do your testing for you in production. You will make changes to your code, and other people will use your code. Finally: there will be bugs, no matter how many tests you write.

The thing about testing is that while it might require a bit more time at the outset, it really does save time in the long run. You’ll be patting yourself on the back the first time a test you wrote catches a bug before it finds its way into production. You’ll be grateful, too, when you have a system in place that can prove that your bug fix really does fix a bug that slips through.

Additional resources

This article just scratches the surface of JavaScript testing, but if you’d like to learn more, check out:

  • My presentation from the 2012 Full Frontal conference in Brighton, UK.
  • Grunt, a tool that helps automate the testing process and lots of other things.
  • Test-Driven JavaScript Development by Christian Johansen, the creator of the Sinon library. It is a dense but informative examination of the practice of testing JavaScript.
0
Your rating: None
Original author: 
(author unknown)

Great design is a product of care and attention applied to areas that matter, resulting in a useful, understandable, and hopefully beautiful user interface. But don’t be fooled into thinking that design is left only for designers.

There is a lot of design in code, and I don’t mean code that builds the user interface—I mean the design of code.

Well-designed code is much easier to maintain, optimize, and extend, making for more efficient developers. That means more focus and energy can be spent on building great things, which makes everyone happy—users, developers, and stakeholders.

There are three high-level, language-agnostic aspects to code design that are particularly important.

  1. System architecture—The basic layout of the codebase. Rules that govern how various components, such as models, views, and controllers, interact with each other.
  2. Maintainability—How well can the code be improved and extended?
  3. Reusability—How reusable are the application’s components? How easily can each implementation of a component be customized?

In looser languages, specifically JavaScript, it takes a bit of discipline to write well-designed code. The JavaScript environment is so forgiving that it’s easy to throw bits and pieces everywhere and still have things work. Establishing system architecture early (and sticking to it!) provides constraints to your codebase, ensuring consistency throughout.

One approach I’m fond of consists of a tried-and-true software design pattern, the module pattern, whose extensible structure lends itself to a solid system architecture and a maintainable codebase. I like building modules within a jQuery plugin, which makes for beautiful reusability, provides robust options, and exposes a well-crafted API.

Below, I’ll walk through how to craft your code into well-organized components that can be reused in projects to come.

The module pattern

There are a lot of design patterns out there, and equally as many resources on them. Addy Osmani wrote an amazing (free!) book on design patterns in JavaScript, which I highly recommend to developers of all levels.

The module pattern is a simple structural foundation that can help keep your code clean and organized. A “module” is just a standard object literal containing methods and properties, and that simplicity is the best thing about this pattern: even someone unfamiliar with traditional software design patterns would be able to look at the code and instantly understand how it works.

In applications that use this pattern, each component gets its own distinct module. For example, to build autocomplete functionality, you’d create a module for the textfield and a module for the results list. These two modules would work together, but the textfield code wouldn’t touch the results list code, and vice versa.

That decoupling of components is why the module pattern is great for building solid system architecture. Relationships within the application are well-defined; anything related to the textfield is managed by the textfield module, not strewn throughout the codebase—resulting in clear code.

Another benefit of module-based organization is that it is inherently maintainable. Modules can be improved and optimized independently without affecting any other part of the application.

I used the module pattern for the basic structure of jPanelMenu, the jQuery plugin I built for off-canvas menu systems. I’ll use that as an example to illustrate the process of building a module.

Building a module

To begin, I define three methods and a property that are used to manage the interactions of the menu system.

var jpm = {
    animated: true,
    openMenu: function( ) {
        …
        this.setMenuStyle( );
    },
    closeMenu: function( ) {
        …
        this.setMenuStyle( );
    },
    setMenuStyle: function( ) { … }
};

The idea is to break down code into the smallest, most reusable bits possible. I could have written just one toggleMenu( ) method, but creating distinct openMenu( ) and closeMenu( ) methods provides more control and reusability within the module.

Notice that calls to module methods and properties from within the module itself (such as the calls to setMenuStyle( )) are prefixed with the this keyword—that’s how modules access their own members.

That’s the basic structure of a module. You can continue to add methods and properties as needed, but it doesn’t get any more complex than that. After the structural foundations are in place, the reusability layer—options and an exposed API—can be built on top.

jQuery plugins

The third aspect of well-designed code is probably the most crucial: reusability. This section comes with a caveat. While there are obviously ways to build and implement reusable components in raw JavaScript (we’re about 90 percent of the way there with our module above), I prefer to build jQuery plugins for more complex things, for a few reasons.

Most importantly, it’s a form of unobtrusive communication. If you used jQuery to build a component, you should make that obvious to those implementing it. Building the component as a jQuery plugin is a great way to say that jQuery is required.

In addition, the implementation code will be consistent with the rest of the jQuery-based project code. That’s good for aesthetic reasons, but it also means (to an extent) that developers can predict how to interact with the plugin without too much research. Just one more way to build a better developer interface.

Before you begin building a jQuery plugin, ensure that the plugin does not conflict with other JavaScript libraries using the $ notation. That’s a lot simpler than it sounds—just wrap your plugin code like so:

(function($) {
    // jQuery plugin code here
})(jQuery);

Next, we set up our plugin and drop our previously built module code inside. A plugin is just a method defined on the jQuery ($) object.

(function($) {
    $.jPanelMenu = function( ) {
        var jpm = {
            animated: true,
            openMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            closeMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            setMenuStyle: function( ) { … }
        };
    };
})(jQuery);

All it takes to use the plugin is a call to the function you just created.

var jpm = $.jPanelMenu( );

Options

Options are essential to any truly reusable plugin because they allow for customizations to each implementation. Every project brings with it a slew of design styles, interaction types, and content structures. Customizable options help ensure that you can adapt the plugin to fit within those project constraints.

It’s best practice to provide good default values for your options. The easiest way to do that is to use jQuery’s $.extend( ) method, which accepts (at least) two arguments.

As the first argument of $.extend( ), define an object with all available options and their default values. As the second argument, pass through the passed-in options. This will merge the two objects, overriding the defaults with any passed-in options.

(function($) {
    $.jPanelMenu = function(options) {
        var jpm = {
            options: $.extend({
                'animated': true,
                'duration': 500,
                'direction': 'left'
            }, options),
            openMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            closeMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            setMenuStyle: function( ) { … }
        };
    };
})(jQuery);

Beyond providing good defaults, options become almost self-documenting—someone can look at the code and see all of the available options immediately.

Expose as many options as is feasible. The customization will help in future implementations, and flexibility never hurts.

API

Options are terrific ways to customize how a plugin works. An API, on the other hand, enables extensions to the plugin’s functionality by exposing methods and properties for the implementation code to take advantage of.

While it’s great to expose as much as possible through an API, the outside world shouldn’t have access to all internal methods and properties. Ideally, you should expose only the elements that will be used.

In our example, the exposed API should include calls to open and close the menu, but nothing else. The internal setMenuStyle( ) method runs when the menu opens and closes, but the public doesn’t need access to it.

To expose an API, return an object with any desired methods and properties at the end of the plugin code. You can even map returned methods and properties to those within the module code—this is where the beautiful organization of the module pattern really shines.

(function($) {
    $.jPanelMenu = function(options) {
        var jpm = {
            options: $.extend({
                'animated': true,
                'duration': 500,
                'direction': 'left'
            }, options),
            openMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            closeMenu: function( ) {
                …
                this.setMenuStyle( );
            },
            setMenuStyle: function( ) { … }
        };

        return {
            open: jpm.openMenu,
            close: jpm.closeMenu,
            someComplexMethod: function( ) { … }
        };
    };
})(jQuery);

API methods and properties will be available through the object returned from the plugin initialization.

var jpm = $.jPanelMenu({
    duration: 1000,
    …
});
jpm.open( );

Polishing developer interfaces

With just a few simple constructs and guidelines, we’ve built ourselves a reusable, extensible plugin that will help make our lives easier. Like any part of what we do, experiment with this structure to see if it works for you, your team, and your workflow.

Whenever I find myself building something with a potential for reuse, I break it out into a module-based jQuery plugin. The best part about this approach is that it forces you to use—and test—the code you write. By using something as you build it, you’ll quickly identify strengths, discover shortcomings, and plan changes.

This process leads to battle-tested code ready for open-source contributions, or to be sold and distributed. I’ve released my (mostly) polished plugins as open-source projects on GitHub.

Even if you aren’t building something to be released in the wild, it’s still important to think about the design of your code. Your future self will thank you.

0
Your rating: None

  

At some point or another, you will find yourself writing JavaScript code that exceeds the couple of lines from a jQuery plugin. Your code will do a whole lot of things; it will (ideally) be used by many people who will approach your code differently. They have different needs, knowledge and expectations.

This article covers the most important things that you will need to consider before and while writing your own utilities and libraries. We’ll focus on how to make your code accessible to other developers. A couple of topics will be touching upon jQuery for demonstration, yet this article is neither about jQuery nor about writing plugins for it.

“The computer is a moron.”
— Peter Drucker

Don’t write code for morons, write for humans! Let’s dive into designing the APIs that developers will love using.

Time Spent On Creating Vs Time Spent On Using

Fluent Interface

The Fluent Interface is often referred to as Method Chaining (although that’s only half the truth). To beginners it looks like the jQuery style. While I believe the API style was a key ingredient in jQuery’s success, it wasn’t invented by them — credits seem to go to Martin Fowler who coined the term back in 2005, roughly a year before jQuery was released. Fowler only gave the thing a name, though — Fluent Interfaces have been around for a much longer time.

Aside from major simplifications, jQuery offered to even out severe browser differences. It has always been the Fluent Interface that I have loved most about this extremely successful library. I have come to enjoy this particular API style so much that it became immediately apparent that I wanted this style for URI.js, as well. While tuning up the URI.js API, I constantly looked through the jQuery source to find the little tricks that would make my implementation as simple as possible. I found out that I was not alone in this endeavor. Lea Verou created chainvas — a tool to wrap regular getter/setter APIs into sweet fluent interfaces. Underscore’s _.chain() does something similar. In fact, most of the newer generation libraries support method chaining.

Method Chaining

The general idea of Method Chaining is to achieve code that is as fluently readable as possible and thus quicker to understand. With Method Chaining we can form code into sentence-like sequences, making code easy to read, while reducing noise in the process:

// regular API calls to change some colors and add an event-listener
var elem = document.getElementById("foobar");
elem.style.background = "red";
elem.style.color = "green";
elem.addEventListener('click', function(event) {
  alert("hello world!");
}, true);

// (imaginary) method chaining API
DOMHelper.getElementById('foobar')
  .setStyle("background", "red")
  .setStyle("color", "green")
  .addEvent("click", function(event) {
    alert("hello world");
  });

Note how we didn’t have to assign the element’s reference to a variable and repeat that over and over again.

Command Query Separation

Command and Query Separation (CQS) is a concept inherited from imperative programming. Functions that change the state (internal values) of an object are called commands, functions that retrieve values are called queries. In principle, queries return data, commands change the state — but neither does both. This concept is one of the foundations of the everyday getter and setter methods we see in most libraries today. Since Fluent Interfaces return a self-reference for chaining method calls, we’re already breaking the rule for commands, as they are not supposed to return anything. On top of this (easy to ignore) trait, we (deliberately) break with this concept to keep APIs as simple as possible. An excellent example for this practice is jQuery’s css() method:

var $elem = jQuery("#foobar");

// CQS - command
$elem.setCss("background", "green");
// CQS - query
$elem.getCss("color") === "red";

// non-CQS - command
$elem.css("background", "green");
// non-CQS - query
$elem.css("color") === "red";

As you can see, getter and setter methods are merged into a single method. The action to perform (namely, query or command) is decided by the amount of arguments passed to the function, rather than by which function was called. This allows us to expose fewer methods and in turn type less to achieve the same goal.

It is not necessary to compress getters and setters into a single method in order to create a fluid interface — it boils down to personal preference. Your documentation should be very clear with the approach you’ve decided on. I will get into documenting APIs later, but at this point I would like to note that multiple function signatures may be harder to document.

Going Fluent

While method chaining already does most of the job for going fluent, you’re not off the hook yet. To illustrate the next step of fluent, we’re pretending to write a little library handling date intervals. An interval starts with a date and ends with a date. A date is not necessarily connected to an interval. So we come up with this simple constructor:

// create new date interval
var interval = new DateInterval(startDate, endDate);
// get the calculated number of days the interval spans
var days = interval.days();

While this looks right at first glance, this example shows what’s wrong:

var startDate = new Date(2012, 0, 1);
var endDate = new Date(2012, 11, 31)
var interval = new DateInterval(startDate, endDate);
var days = interval.days(); // 365

We’re writing out a whole bunch of variables and stuff we probably won’t need. A nice solution to the problem would be to add a function to the Date object in order to return an interval:

// DateInterval creator for fluent invocation
Date.prototype.until = function(end) {

  // if we weren't given a date, make one
  if (!(end instanceof Date)) {
    // create date from given arguments,
    // proxy the constructor to allow for any parameters
    // the Date constructor would've taken natively
    end = Date.apply(null, 
      Array.prototype.slice.call(arguments, 0)
    );
  }

  return new DateInterval(this, end);
};

Now we can create that DateInterval in a fluent, easy to type-and-read fashion:

var startDate = new Date(2012, 0, 1);
var interval = startDate.until(2012, 11, 31);
var days = interval.days(); // 365

// condensed fluent interface call:
var days = (new Date(2012, 0, 1))
  .until(2012, 11, 31) // returns DateInterval instance
  .days(); // 365

As you can see in this last example, there are less variables to declare, less code to write, and the operation almost reads like an english sentence. With this example you should have realized that method chaining is only a part of a fluent interface, and as such, the terms are not synonymous. To provide fluency, you have to think about code streams — where are you coming from and where you are headed.

This example illustrated fluidity by extending a native object with a custom function. This is as much a religion as using semicolons or not. In Extending built-in native objects. Evil or not? kangax explains the ups and downs of this approach. While everyone has their opinions about this, the one thing everybody agrees on is keeping things consistent. As an aside, even the followers of “Don’t pollute native objects with custom functions” would probably let the following, still somewhat fluid trick slide:

String.prototype.foo = function() {
  return new Foo(this);
}

"I'm a native object".foo()
  .iAmACustomFunction();

With this approach your functions are still within your namespace, but made accessible through another object. Make sure your equivalent of .foo() is a non-generic term, something highly unlikely to collide with other APIs. Make sure you provide proper .valueOf() and .toString() methods to convert back to the original primitive types.

Consistency

Jake Archibald once had a slide defining Consistency. It simply read Not PHP. Do. Not. Ever. Find yourself naming functions like str_repeat(), strpos(), substr(). Also, don’t ever shuffle around positions of arguments. If you declared find_in_array(haystack, needle) at some point, introducing findInString(needle, haystack) will invite an angry mob of zombies to rise from their graves to hunt you down and force you to write delphi for the rest of your life!

Naming Things

“There are only two hard problems in computer science: cache-invalidation and naming things.”
— Phil Karlton

I’ve been to numerous talks and sessions trying to teach me the finer points of naming things. I haven’t left any of them without having heard the above said quote, nor having learnt how to actually name things. My advice boils down to keep it short but descriptive and go with your gut. But most of all, keep it consistent.

The DateInterval example above introduced a method called until(). We could have named that function interval(). The latter would have been closer to the returned value, while the former is more humanly readable. Find a line of wording you like and stick with it. Consistency is 90% of what matters. Choose one style and keep that style — even if you find yourself disliking it at some point in the future.

Handling Arguments

Good Intentions

How your methods accept data is more important than making them chainable. While method chaining is a pretty generic thing that you can easily make your code do, handling arguments is not. You’ll need to think about how the methods you provide are most likely going to be used. Is code that uses your API likely to repeat certain function calls? Why are these calls repeated? How could your API help the developer to reduce the noise of repeating method calls?

jQuery’s css() method can set styles on a DOM element:

jQuery("#some-selector")
  .css("background", "red")
  .css("color", "white")
  .css("font-weight", "bold")
  .css("padding", 10);

There’s a pattern here! Every method invocation is naming a style and specifying a value for it. This calls for having the method accept a map:

jQuery("#some-selector").css({
  "background" : "red",
  "color" : "white",
  "font-weight" : "bold",
  "padding" : 10
});

jQuery’s on() method can register event handlers. Like css() it accepts a map of events, but takes things even further by allowing a single handler to be registered for multiple events:

// binding events by passing a map
jQuery("#some-selector").on({
  "click" : myClickHandler,
  "keyup" : myKeyupHandler,
  "change" : myChangeHandler
});

// binding a handler to multiple events:
jQuery("#some-selector").on("click keyup change", myEventHandler);

You can offer the above function signatures by using the following method pattern:

DateInterval.prototype.values = function(name, value) {
  var map;

  if (jQuery.isPlainObject(name)) {
    // setting a map
    map = name;
  } else if (value !== undefined) {
    // setting a value (on possibly multiple names), convert to map
    keys = name.split(" ");
    map = {};
    for (var i = 0, length = keys.length; i < length; i++) {
      map[keys[i]] = value;
    }
  } else if (name === undefined) {
    // getting all values
    return this.values;
  } else {
    // getting specific value
    return this.values[name];
  }

  for (var key in map) {
    this.values[name] = map[key];
  }

  return this;
};

If you are working with collections, think about what you can do to reduce the number of loops an API user would probably have to make. Say we had a number of <input> elements for which we want to set the default value:

<input type="text" value="" data-default="foo">
<input type="text" value="" data-default="bar">
<input type="text" value="" data-default="baz">

We’d probably go about this with a loop:

jQuery("input").each(function() {
  var $this = jQuery(this);
  $this.val($this.data("default"));
});

What if we could bypass that method with a simple callback that gets applied to each <input> in the collection? jQuery developers have thought of that and allow us to write less™:

jQuery("input").val(function() {
  return jQuery(this).data("default");
});

It’s the little things like accepting maps, callbacks or serialized attribute names, that make using your API not only cleaner, but more comfortable and efficient to use. Obviously not all of your APIs’ methods will benefit from this method pattern — it’s up to you to decide where all this makes sense and where it is just a waste of time. Try to be as consistent about this as humanly possible. Reduce the need for boilerplate code with the tricks shown above and people will invite you over for a drink.

Handling Types

Whenever you define a function that will accept arguments, you decide what data that function accepts. A function to calculate the number of days between two dates could look like:

DateInterval.prototype.days = function(start, end) {
  return Math.floor((end - start) / 86400000);
};

As you can see, the function expects numeric input — a millisecond timestamp, to be exact. While the function does what we intended it to do, it is not very versatile. What if we’re working with Date objects or a string representation of a date? Is the user of this function supposed to cast data all the time? No! Simply verifying the input and casting it to whatever we need it to be should be done in a central place, not cluttered throughout the code using our API:

DateInterval.prototype.days = function(start, end) {
  if (!(start instanceof Date)) {
    start = new Date(start);
  }
  if (!(end instanceof Date)) {
    end = new Date(end);
  }

  return Math.floor((end.getTime() - start.getTime()) / 86400000);
};

By adding these six lines we’ve given the function the power to accept a Date object, a numeric timestamp, or even a string representation like Sat Sep 08 2012 15:34:35 GMT+0200 (CEST). We do not know how and for what people are going to use our code, but with a little foresight, we can make sure there is little pain with integrating our code.

The experienced developer can spot another problem in the example code. We’re assuming start comes before end. If the API user accidentally swapped the dates, he’d be given a negative value for the number of days between start and end. Stop and think about these situations carefully. If you’ve come to the conclusion that a negative value doesn’t make sense, fix it:

DateInterval.prototype.days = function(start, end) {
  if (!(start instanceof Date)) {
    start = new Date(start);
  }
  if (!(end instanceof Date)) {
    end = new Date(end);
  }

  return Math.abs(Math.floor((end.getTime() - start.getTime()) / 86400000));
};

JavaScript allows type casting a number of ways. If you’re dealing with primitives (string, number, boolean) it can get as simple (as in “short”) as:

function castaway(some_string, some_integer, some_boolean) {
  some_string += "";
  some_integer += 0; // parseInt(some_integer, 10) is the safer bet
  some_boolean = !!some_boolean;
}

I’m not advocating you to do this everywhere and at all times. But these innocent looking lines may save time and some suffering while integrating your code.

Treating undefined as an Expected Value

There will come a time when undefined is a value that your API actually expects to be given for setting an attribute. This might happen to “unset” an attribute, or simply to gracefully handle bad input, making your API more robust. To identify if the value undefined has actually been passed by your method, you can check the arguments object:

function testUndefined(expecting, someArgument) {
  if (someArgument === undefined) {
    console.log("someArgument was undefined");
  }
  if (arguments.length > 1) {
    console.log("but was actually passed in");
  }
}

testUndefined("foo");
// prints: someArgument was undefined
testUndefined("foo", undefined);
// prints: someArgument was undefined, but was actually passed in

Named Arguments

event.initMouseEvent(
  "click", true, true, window, 
  123, 101, 202, 101, 202, 
  true, false, false, false, 
  1, null);

The function signature of Event.initMouseEvent is a nightmare come true. There is no chance any developer will remember what that 1 (second to last parameter) means without looking it up in the documentation. No matter how good your documentation is, do what you can so people don’t have to look things up!

How Others Do It

Looking beyond our beloved language, we find Python knowing a concept called named arguments. It allows you to declare a function providing default values for arguments, allowing your attributed names to be stated in the calling context:

function namesAreAwesome(foo=1, bar=2) {
  console.log(foo, bar);
}

namesAreAwesome();
// prints: 1, 2

namesAreAwesome(3, 4);
// prints: 3, 4

namesAreAwesome(foo=5, bar=6);
// prints: 5, 6

namesAreAwesome(bar=6);
// prints: 1, 6

Given this scheme, initMouseEvent() could’ve looked like a self-explaining function call:

event.initMouseEvent(
  type="click", 
  canBubble=true, 
  cancelable=true, 
  view=window, 
  detail=123,
  screenX=101, 
  screenY=202, 
  clientX=101, 
  clientY=202, 
  ctrlKey=true, 
  altKey=false, 
  shiftKey=false, 
  metaKey=false, 
  button=1, 
  relatedTarget=null);

In JavaScript this is not possible today. While “the next version of JavaScript” (frequently called ES.next, ES6, or Harmony) will have default parameter values and rest parameters, there is still no sign of named parameters.

Argument Maps

JavaScript not being Python (and ES.next being light years away), we’re left with fewer choices to overcome the obstacle of “argument forests”. jQuery (and pretty much every other decent API out there) chose to work with the concept of “option objects”. The signature of jQuery.ajax() provides a pretty good example. Instead of accepting numerous arguments, we only accept an object:

function nightmare(accepts, async, beforeSend, cache, complete, /* and 28 more */) {
  if (accepts === "text") {
    // prepare for receiving plain text
  }
}

function dream(options) {
  options = options || {};
  if (options.accepts === "text") {
    // prepare for receiving plain text
  }
}

Not only does this prevent insanely long function signatures, it also makes calling the function more descriptive:

nightmare("text", true, undefined, false, undefined, /* and 28 more */);

dream({
  accepts: "text",
  async: true,
  cache: false
});

Also, we do not have to touch the function signature (adding a new argument) should we introduce a new feature in a later version.

Default Argument Values

jQuery.extend(), _.extend() and Protoype’s Object.extend are functions that let you merge objects, allowing you to throw your own preset options object into the mix:

var default_options = {
  accepts: "text",
  async: true,
  beforeSend: null,
  cache: false,
  complete: null,
  // …
};

function dream(options) {
  var o = jQuery.extend({}, default_options, options || {});
  console.log(o.accepts);
}

// make defaults public
dream.default_options = default_options;

dream({ async: false });
// prints: "text"

You’re earning bonus points for making the default values publicly accessible. With this, anyone can change accepts to “json” in a central place, and thus avoid specifying that option over and over again. Note that the example will always append || {} to the initial read of the option object. This allows you to call the function without an argument given.

Good Intentions — a.k.a. “Pitfalls”

Now that you know how to be truly flexible in accepting arguments, we need to come back to an old saying:

“With great power comes great responsibility!”
— Voltaire

As with most weakly-typed languages, JavaScript does automatic casting when it needs to. A simple example is testing the truthfulness:

var foo = 1;
var bar = true;

if (foo) {
  // yep, this will execute
}

if (bar) {
  // yep, this will execute
}

We’re quite used to this automatic casting. We’re so used to it, that we forget that although something is truthful, it may not be the boolean truth. Some APIs are so flexible they are too smart for their own good. Take a look at the signatures of jQuery.toggle():

.toggle( /* int */ [duration] [, /* function */  callback] )
.toggle( /* int */ [duration] [, /* string */  easing] [, /* function */ callback] )
.toggle( /* bool */ showOrHide )

It will take us some time decrypting why these behave entirely different:

var foo = 1;
var bar = true;
var $hello = jQuery(".hello");
var $world = jQuery(".world");

$hello.toggle(foo);
$world.toggle(bar);

We were expecting to use the showOrHide signature in both cases. But what really happened is $hello doing a toggle with a duration of one millisecond. This is not a bug in jQuery, this is a simple case of expectation not met. Even if you’re an experienced jQuery developer, you will trip over this from time to time.

You are free to add as much convenience / sugar as you like — but do not sacrifice a clean and (mostly) robust API along the way. If you find yourself providing something like this, think about providing a separate method like .toggleIf(bool) instead. Whatever choice you make, keep your API consistent!

Extensibility

Developing Possibilities

With option objects, we’ve covered the topic of extensible configuration. Let’s talk about allowing the API user to extend the core and API itself. This is an important topic, as it allows your code to focus on the important things, while having API users implement edge-cases themselves. Good APIs are concise APIs. Having a hand full of configuration options is fine, but having a couple dozen of them makes your API feel bloated and opaque. Focus on the primary-use cases, only do the things most of your API users will need. Everything else should be left up to them. To allow API users to extend your code to suit their needs, you have a couple of options…

Callbacks

Callbacks can be used to achieve extensibility by configuration. You can use callbacks to allow the API user to override certain parts of your code. When you feel specific tasks may be handled differently than your default code, refactor that code into a configurable callback function to allow an API user to easily override that:

var default_options = {
  // ...
  position: function($elem, $parent) {
    $elem.css($parent.position());
  }
};

function Widget(options) {
  this.options = jQuery.extend({}, default_options, options || {});
  this.create();
};

Widget.prototype.create = function() {
  this.$container = $("<div></div>").appendTo(document.body);
  this.$thingie = $("<div></div>").appendTo(this.$container);
  return this;
};

Widget.protoype.show = function() {
  this.options.position(this.$thingie, this.$container);
  this.$thingie.show();
  return this;
};
var widget = new Widget({
  position: function($elem, $parent) {
    var position = $parent.position();
    // position $elem at the lower right corner of $parent
    position.left += $parent.width();
    position.top += $parent.height();
    $elem.css(position);
  }
});
widget.show();

Callbacks are also a generic way to allow API users to customize elements your code has created:

// default create callback doesn't do anything
default_options.create = function($thingie){};

Widget.prototype.create = function() {
  this.$container = $("<div></div>").appendTo(document.body);
  this.$thingie = $("<div></div>").appendTo(this.$container);
  // execute create callback to allow decoration
  this.options.create(this.$thingie);
  return this;
};
var widget = new Widget({
  create: function($elem) {
    $elem.addClass('my-style-stuff');
  }
});
widget.show();

Whenever you accept callbacks, be sure to document their signature and provide examples to help API users customize your code. Make sure you’re consistent about the context (where this points to) in which callbacks are executed in, and the arguments they accept.

Events

Events come naturally when working with the DOM. In larger application we use events in various forms (e.g. PubSub) to enable communication between modules. Events are particularly useful and feel most natural when dealing with UI widgets. Libraries like jQuery offer simple interfaces allowing you to easily conquer this domain.

Events interface best when there is something happening — hence the name. Showing and hiding a widget could depend on circumstances outside of your scope. Updating the widget when it’s shown is also a very common thing to do. Both can be achieved quite easily using jQuery’s event interface, which even allows for the use of delegated events:

Widget.prototype.show = function() {
  var event = jQuery.Event("widget:show");
  this.$container.trigger(event);
  if (event.isDefaultPrevented()) {
    // event handler prevents us from showing
    return this;
  }

  this.options.position(this.$thingie, this.$container);
  this.$thingie.show();
  return this;
};
// listen for all widget:show events
$(document.body).on('widget:show', function(event) {
  if (Math.random() > 0.5) {
    // prevent widget from showing
    event.preventDefault();
  }

  // update widget's data
  $(this).data("last-show", new Date());
});

var widget = new Widget();
widget.show();

You can freely choose event names. Avoid using native events for proprietary things and consider namespacing your events. jQuery UI’s event names are comprised of the widget’s name and the event name dialogshow. I find that hard to read and often default to dialog:show, mainly because it is immediately clear that this is a custom event, rather than something some browser might have secretly implemented.

Hooks

Traditional getter and setter methods can especially benefit from hooks. Hooks usually differ from callbacks in their number and how they’re registered. Where callbacks are usually used on an instance level for a specific task, hooks are usually used on a global level to customize values or dispatch custom actions. To illustrate how hooks can be used, we’ll take a peek at jQuery’s cssHooks:

// define a custom css hook
jQuery.cssHooks.custombox = {
  get: function(elem, computed, extra) {
    return $.css(elem, 'borderRadius') == "50%"
      ? "circle"
      : "box";
  },
  set: function(elem, value) {
    elem.style.borderRadius = value == "circle"
      ? "50%"
      : "0";
  }
};

// have .css() use that hook
$("#some-selector").css("custombox", "circle");

By registering the hook custombox we’ve given jQuery’s .css() method the ability to handle a CSS property it previously couldn’t. In my article jQuery hooks, I explain the other hooks that jQuery provides and how they can be used in the field. You can provide hooks much like you would handle callbacks:

DateInterval.nameHooks = {
  "yesterday" : function() {
    var d = new Date();
    d.setTime(d.getTime() - 86400000);
    d.setHours(0);
    d.setMinutes(0);
    d.setSeconds(0);
    return d;
  }
};

DateInterval.prototype.start = function(date) {
  if (date === undefined) {
    return new Date(this.startDate.getTime());
  }

  if (typeof date === "string" && DateInterval.nameHooks[date]) {
    date = DateInterval.nameHooks[date]();
  }

  if (!(date instanceof Date)) {
    date = new Date(date);
  }

  this.startDate.setTime(date.getTime());
  return this;
};
var di = new DateInterval();
di.start("yesterday");

In a way, hooks are a collection of callbacks designed to handle custom values within your own code. With hooks you can stay in control of almost everything, while still giving API users the option to customize.

Generating Accessors

Duplication

Any API is likely to have multiple accessor methods (getters, setters, executors) doing similar work. Coming back to our DateInterval example, we’re most likely providing start() and end() to allow manipulation of intervals. A simple solution could look like:

DateInterval.prototype.start = function(date) {
  if (date === undefined) {
    return new Date(this.startDate.getTime());
  }

  this.startDate.setTime(date.getTime());
  return this;
};

DateInterval.prototype.end = function(date) {
  if (date === undefined) {
    return new Date(this.endDate.getTime());
  }

  this.endDate.setTime(date.getTime());
  return this;
};

As you can see we have a lot of repeating code. A DRY (Don’t Repeat Yourself) solution might use this generator pattern:

var accessors = ["start", "end"];
for (var i = 0, length = accessors.length; i < length; i++) {
  var key = accessors[i];
  DateInterval.prototype[key] = generateAccessor(key);
}

function generateAccessor(key) {
  var value = key + "Date";
  return function(date) {
    if (date === undefined) {
      return new Date(this[value].getTime());
    }

    this[value].setTime(date.getTime());
    return this;
  };
}

This approach allows you to generate multiple similar accessor methods, rather than defining every method separately. If your accessor methods require more data to setup than just a simple string, consider something along the lines of:

var accessors = {"start" : {color: "green"}, "end" : {color: "red"}};
for (var key in accessors) {
  DateInterval.prototype[key] = generateAccessor(key, accessors[key]);
}

function generateAccessor(key, accessor) {
  var value = key + "Date";
  return function(date) {
    // setting something up 
    // using `key` and `accessor.color`
  };
}

In the chapter Handling Arguments we talked about a method pattern to allow your getters and setters to accept various useful types like maps and arrays. The method pattern itself is a pretty generic thing and could easily be turned into a generator:

function wrapFlexibleAccessor(get, set) {
  return function(name, value) {
    var map;

    if (jQuery.isPlainObject(name)) {
      // setting a map
      map = name;
    } else if (value !== undefined) {
      // setting a value (on possibly multiple names), convert to map
      keys = name.split(" ");
      map = {};
      for (var i = 0, length = keys.length; i < length; i++) {
        map[keys[i]] = value;
      }
    } else {
      return get.call(this, name);
    }

    for (var key in map) {
      set.call(this, name, map[key]);
    }

    return this;
  };
}

DateInterval.prototype.values = wrapFlexibleAccessor(
  function(name) { 
    return name !== undefined 
      ? this.values[name]
      : this.values;
  },
  function(name, value) {
    this.values[name] = value;
  }
);

Digging into the art of writing DRY code is well beyond this article. Rebecca Murphey wrote Patterns for DRY-er JavaScript and Mathias Bynens’ slide deck on how DRY impacts JavaScript performance are a good start, if you’re new to the topic.

The Reference Horror

Unlike other languages, JavaScript doesn’t know the concepts of pass by reference nor pass by value. Passing data by value is a safe thing. It makes sure data passed to your API and data returned from your API may be modified outside of your API without altering the state within. Passing data by reference is often used to keep memory overhead low, values passed by reference can be changed anywhere outside your API and affect state within.

In JavaScript there is no way to tell if arguments should be passed by reference or value. Primitives (strings, numbers, booleans) are treated as pass by value, while objects (any object, including Array, Date) are handled in a way that’s comparable to by reference. If this is the first you’re hearing about this topic, let the following example enlighten you:

// by value
function addOne(num) {
  num = num + 1; // yes, num++; does the same
  return num;
}

var x = 0;
var y = addOne(x);
// x === 0 <--
// y === 1

// by reference
function addOne(obj) {
  obj.num = obj.num + 1;
  return obj;
}

var ox = {num : 0};
var oy = addOne(ox);
// ox.num === 1 <--
// oy.num === 1

The by reference handling of objects can come back and bite you if you’re not careful. Going back to the DateInterval example, check out this bugger:

var startDate = new Date(2012, 0, 1);
var endDate = new Date(2012, 11, 31)
var interval = new DateInterval(startDate, endDate);
endDate.setMonth(0); // set to january
var days = interval.days(); // got 31 but expected 365 - ouch!

Unless the constructor of DateInterval made a copy (clone is the technical term for a copy) of the values it received, any changes to the original objects will reflect on the internals of DateInterval. This is usually not what we want or expect.

Note that the same is true for values returned from your API. If you simply return an internal object, any changes made to it outside of your API will be reflected on your internal data. This is most certainly not what you want. jQuery.extend(), _.extend() and Protoype’s Object.extend allow you to easily escape the reference horror.

If this summary did not suffice, read the excellent chapter By Value Versus by Reference from O’Reilly’s JavaScript – The Definitive Guide.

The Continuation Problem

In a fluent interface, all methods of a chain are executed, regardless of the state that the base object is in. Consider calling a few methods on a jQuery instance that contain no DOM elements:

jQuery('.wont-find-anything')
  // executed although there is nothing to execute against
  .somePlugin().someOtherPlugin();

In non-fluent code we could have prevented those functions from being executed:

var $elem = jQuery('.wont-find-anything');
if ($elem.length) {
  $elem.somePlugin().someOtherPlugin();
}

Whenever we chain methods, we lose the ability to prevent certain things from happening — we can’t escape from the chain. As long as the API developer knows that objects can have a state where methods don’t actually do anything but return this;, everything is fine. Depending on what your methods do internally, it may help to prepend a trivial is-empty detection:

jQuery.fn.somePlugin = function() {
  if (!this.length) {
    // "abort" since we've got nothing to work with
    return this;
  }

  // do some computational heavy setup tasks
  for (var i = 10000; i > 0; i--) {
    // I'm just wasting your precious CPU!
    // If you call me often enough, I'll turn
    // your laptop into a rock-melting jet engine
  }

  return this.each(function() {
    // do the actual job
  });
};

Handling Errors

Fail Faster

I was lying when I said we couldn’t escape from the chain — there is an Exception to the rule (pardon the pun ☺).

We can always eject by throwing an Error (Exception). Throwing an Error is considered a deliberate abortion of the current flow, most likely because you came into a state that you couldn’t recover from. But beware — not all Errors are helping the debugging developer:

// jQuery accepts this
$(document.body).on('click', {});

// on click the console screams
//   TypeError: ((p.event.special[l.origType] || {}).handle || l.handler).apply is not a function 
//   in jQuery.min.js on Line 3

Errors like these are a major pain to debug. Don’t waste other people’s time. Inform an API user if he did something stupid:

if (Object.prototype.toString.call(callback) !== '[object Function]') { // see note
  throw new TypeError("callback is not a function!");
}

Note: typeof callback === "function" should not be used, as older browsers may report objects to be a function, which they are not. In Chrome (up to version 12) RegExp is such a case. For convenience, use jQuery.isFunction() or _.isFunction().

Most libraries that I have come across, regardless of language (within the weak-typing domain) don’t care about rigorous input validation. To be honest, my own code only validates where I anticipate developers stumbling. Nobody really does it, but all of us should. Programmers are a lazy bunch — we don’t write code just for the sake of writing code or for some cause we don’t truly believe in. The developers of Perl6 have recognized this being a problem and decided to incorporate something called Parameter Constraints. In JavaScript, their approach might look something like this:

function validateAllTheThings(a, b {where typeof b === "numeric" and b < 10}) {
  // Interpreter should throw an Error if b is
  // not a number or greater than 9
}

While the syntax is as ugly as it gets, the idea is to make validation of input a top-level citizen of the language. JavaScript is nowhere near being something like that. That’s fine — I couldn’t see myself cramming these constraints into the function signature anyways. It’s admitting the problem (of weakly-typed languages) that is the interesting part of this story.

JavaScript is neither weak nor inferior, we just have to work a bit harder to make our stuff really robust. Making code robust does not mean accepting any data, waving your wand and getting some result. Being robust means not accepting rubbish and telling the developer about it.

Think of input validation this way: A couple of lines of code behind your API can make sure that no developer has to spend hours chasing down weird bugs because they accidentally gave your code a string instead of a number. This is the one time you can tell people they’re wrong and they’ll actually love you for doing so.

Going Asynchronous

So far we’ve only looked at synchronous APIs. Asynchronous methods usually accept a callback function to inform the outside world, once a certain task is finished. This doesn’t fit too nicely into our fluent interface scheme, though:

Api.protoype.async = function(callback) {
  console.log("async()");
  // do something asynchronous
  window.setTimeout(callback, 500);
  return this;
};
Api.protoype.method = function() {
  console.log("method()");
  return this;
};
// running things
api.async(function() {
  console.log('callback()');
}).method();

// prints: async(), method(), callback()

This example illustrates how the asynchronous method async() begins its work but immediately returns, leading to method() being invoked before the actual task of async() completed. There are times when we want this to happen, but generally we expect method() to execute after async() has completed its job.

Deferreds (Promises)

To some extent we can counter the mess that is a mix of asynchronous and synchronous API calls with Promises. jQuery knows them as Deferreds. A Deferred is returned in place of your regular this, which forces you to eject from method chaining. This may seem odd at first, but it effectively prevents you from continuing synchronously after invoking an asynchronous method:

Api.protoype.async = function() {
  var deferred = $.Deferred();
  console.log("async()");

  window.setTimeout(function() {
    // do something asynchronous
    deferred.resolve("some-data");
  }, 500);

  return deferred.promise();
};
api.async().done(function(data) {
  console.log("callback()");
  api.method();
});

// prints: async(), callback(), method()

The Deferred object let’s you register handlers using .done(), .fail(), .always() to be called when the asynchronous task has completed, failed, or regardless of its state. See Promise Pipelines In JavaScript for a more detailed introduction to Deferreds.

Debugging Fluent Interfaces

While Fluent Interfaces are much nicer to develop with, they do come with certain limitations regarding de-buggability.

As with any code, Test Driven Development (TDD) is an easy way to reduce debugging needs. Having written URI.js in TDD, I have not come across major pains regarding debugging my code. However, TDD only reduces the need for debugging — it doesn’t replace it entirely.

Some voices on the internet suggest writing out each component of a chain in their separate lines to get proper line-numbers for errors in a stack trace:

foobar.bar()
  .baz()
  .bam()
  .someError();

This technique does have its benefits (though better debugging is not a solid part of it). Code that is written like the above example is even simpler to read. Line-based differentials (used in version control systems like SVN, GIT) might see a slight win as well. Debugging-wise, it is only Chrome (at the moment), that will show someError() to be on line four, while other browsers treat it as line one.

Adding a simple method to logging your objects can already help a lot — although that is considered “manual debugging” and may be frowned upon by people used to “real” debuggers:

DateInterval.prototype.explain = function() {
  // log the current state to the console
  console.dir(this);
};

var days = (new Date(2012, 0, 1))
  .until(2012, 11, 31) // returns DateInterval instance
  .explain() // write some infos to the console
  .days(); // 365

Function names

Throughout this article you’ve seen a lot of demo code in the style of Foo.prototype.something = function(){}. This style was chosen to keep examples brief. When writing APIs you might want to consider either of the following approaches, to have your console properly identify function names:

Foo.prototype.something = (function something() {
  // yadda yadda
});
Foo.prototype.something = function() {
  // yadda yadda
};
Foo.prototype.something.displayName = "Foo.something";

The first approach has its quirks due to hoisting — unless you wrap your declarations in parentheses like the example shows. The second option displayName was introduced by WebKit and later adopted by Firebug / Firefox. displayName is a bit more code to write out, but allows arbitrary names, including a namespace or associated object. Either of these approaches can help with anonymous functions quite a bit.

Read more on this topic in Named function expressions demystified by kangax.

Documenting APIs

One of the hardest tasks of software development is documenting things. Practically everyone hates doing it, yet everybody laments about bad or missing documentation of the tools they need to use. There is a wide range of tools that supposedly help and automate documenting your code:

At one point or another all of these tool won’t fail to disappoint. JavaScript is a very dynamic language and thus particularly diverse in expression. This makes a lot of things extremely difficult for these tools. The following list features a couple of reasons why I’ve decided to prepare documentation in vanilla HTML, markdown or DocBoock (if the project is large enough). jQuery, for example, has the same issues and doesn’t document their APIs within their code at all.

  1. Function signatures aren’t the only documentation you need, but most tools focus only on them.
  2. Example code goes a long way in explaining how something works. Regular API docs usually fail to illustrate that with a fair trade-off.
  3. API docs usually fail horribly at explaining things behind the scenes (flow, events, etc).
  4. Documenting methods with multiple signatures is usually a real pain.
  5. Documenting methods using option objects is often not a trivial task.
  6. Generated Methods aren’t easily documented, neither are default callbacks.

If you can’t (or don’t) want to adjust your code to fit one of the listed documentation tools, projects like Document-Bootstrap might save you some time setting up your home brew documentation.

Make sure your Documentation is more than just some generated API doc. Your users will appreciate any examples you provide. Tell them how your software flows and which events are involved when doing something. Draw them a map, if it helps their understanding of whatever it is your software is doing. And above all: keep your docs in sync with your code!

Self-Explanatory Code

Providing good documentation will not keep developers from actually reading your code — your code is a piece of documentation itself. Whenever the documentation doesn’t suffice (and every documentation has its limits), developers fall back to reading the actual source to get their questions answered. Actually, you are one of them as well. You are most likely reading your own code again and again, with weeks, months or even years in between.

You should be writing code that explains itself. Most of the time this is a non-issue, as it only involves you thinking harder about naming things (functions, variables, etc) and sticking to a core concept. If you find yourself writing code comments to document how your code does something, you’re most likely wasting time — your time, and the reader’s as well. Comment on your code to explain why you solved the problem this particular way, rather than explaining how you solved the problem. The how should become apparent through your code, so don’t repeat yourself. Note that using comments to mark sections within your code or to explain general concepts is totally acceptable.

Conclusion

  • An API is a contract between you (the provider) and the user (the consumer). Don’t just change things between versions.
  • You should invest as much time into the question How will people use my software? as you have put into How does my software work internally?
  • With a couple of simple tricks you can greatly reduce the developer’s efforts (in terms of the lines of code).
  • Handle invalid input as early as possible — throw Errors.
  • Good APIs are flexible, better APIs don’t let you make mistakes.

Continue with Reusable Code for good or for awesome (slides), a Talk by Jake Archibald on designing APIs. Back in 2007 Joshua Bloch gave the presentation How to Design A Good API and Why it Matters at Google Tech Talks. While his talk did not focus on JavaScript, the basic principles that he explained still apply.

Now that you’re up to speed on designing APIs, have a look at Essential JS Design Patterns by Addy Osmani to learn more about how to structure your internal code.

Thanks go out to @bassistance, @addyosmani and @hellokahlil for taking the time to proof this article.

© Rodney Rehm for Smashing Magazine, 2012.

0
Your rating: None

  

I don’t think anyone can deny that the Web has changed the way people teach, learn, and do research. Of course, this doesn’t mean that everything we read online is true and accurate—far from it. But I believe that through honest discussion and objective collaboration, accurate and useful information is much more likely to be the end result of any educational endeavor.

In the final week of November 2011, a smart group of developers launched a project called Move The Web Forward, which you can read more about in Addy Osmani’s Smashing Magazine article.

For this post, I want to focus on one piece of advice given by those developers in that project, under the heading “Write”.

The advice is: Publish what you learn.

As soon as I read that exhortation (which originated with this tweet), I knew this was a project made by a group of people who cared about the Web and that they understand what it takes to move forward as developers, and as an industry.

Let’s explore those four simple words, because I believe that concept is at the heart of how much progress has been made in the front-end development niche. And it’s something that could help almost any industry, in any field.

Just Do It

Very few blogs start out with much traffic at all. Unless the blog is based on an already existing brand that has a lot of exposure, most blogs will begin with very few readers. Even Smashing Magazine, who now has millions of readers, subscribers, and followers, started out with nothing.

CSS-Tricks is another good example of a blog that started out as nothing, and has grown into a thriving, collaborative community. Its founder and curator, Chris Coyier, certainly couldn’t have predicted how much that website would grow. And I’m sure we could come up with additional examples of websites that went from zero to hero in a relatively short time.

Why did they become successful? Because they published what they learned. At one time I somewhat favored the view that too many blogs were being launched. But I think the benefits of so much being published in so many different places outweigh any drawbacks.

Of course, this is not to suggest that the reason you want to publish your thoughts is to “make it big”—that should be secondary, if considered at all. In fact, what you publish doesn’t necessarily have to be on a run-of-the-mill monetized WordPress blog. It could be a GitHub account, a Wiki-style website, a Tumblr feed, or even a bunch of quick tips on a simple Twitter account.

Which brings us to another important supplement to this theme. Immediately after the folks at Move The Web Forward told us to publish what we learn, they made an equally important statement.

Don’t Be Afraid To Make Mistakes

You might be thinking: “Wait. What? Me? Publish a blog? I’ve been coding websites for a measly six months (or some other ostensibly short period of time). Even if people visit my website and read it, my articles will probably get torn to shreds!”

That doesn’t matter. What’s important is that you recognize the value in researching, teaching, collaborating, and correcting mistakes. That’s why the Move The Web Forward folks went on to encourage writers to “keep your posts updated.”

And that’s why Rebecca Murphey, when discussing how to get better at writing JavaScript, said:

“The number one thing that will make you better at writing JavaScript is writing JavaScript. It’s OK if you cringe at it six months from now. It’s OK if you know it could be better if you only understood X, Y, or Z a little bit better. Cultivate dissatisfaction, and fear the day when you aren’t disappointed with the code you wrote last month.”

In this case, Rebecca was talking about actually writing code, not writing about code. But the same principle applies: you will get better when you make mistakes and correct them.

And if you think you’ve made some progress and you have something unique and educational to share, don’t be afraid to offer it to one of the many design and development blogs that will gladly pay you for content.

Comments Are Part Of The Content

There are too many websites that view the readers’ comments as secondary content that is not nearly as valuable as what the author has to say in the main article. Every website should continually make changes or updates to content that is clearly shown to be incorrect. This shows that the publisher wants to provide accurate information, and that they respect the views of their readers.

In fact, you could make the argument that without reader comments, the quality of content on many design and development blogs would not be as strong as it is today. On my own website, I’ve written so many things that were just downright wrong. In some cases, things can be a matter of opinion and personal preference. But in other cases, they’re just factually incorrect. In indisputable cases, I’ve always tried to post updates to articles and credit the commenters who pointed them out.

Teachers Learn By Teaching

Randy Rhoads, a popular rock guitarist (who died in a plane crash in 1982), was well-known for being a guitar teacher. He once said:

“I’ve been playing about 18 years and I started to get a style when I started teaching.”

In other words, he believed that his success as a guitarist was largely impacted by the fact that he spent time teaching his skill to others. The same can be true for any one of us.

I’ve learned so much from readers’ comments and from doing research on stuff that I plan to publish. I’ve even learned from content I never actually did publish. The Move The Web Forward project, once again, summarizes this point quite nicely:

“Teaching is a great learning tool as well. So, even if you are getting started in an area, you’re helping yourself by writing about it as well.”

GitHub Gets It Right

The collaboration level on many projects from the “social coding” website GitHub is truly amazing, and is something that shows how revolutionary the Web really is.

GitHub's method of social coding is revolutionary

Think about a large project like HTML5 Boilerplate. When that project was first released, many front-end devs were amazed at how much front-end knowledge had been packed into a single starting template. Many were even intimidated by it. But what it is today is nothing compared to what it was when it first launched.

Why? Because from the get-go the contributors to the project had the same attitude that Paul Irish expressed in the launch post of his blog:

“I’m very interested in your contributions… what else deserves to be in this base template?”

With those words, Paul began what might be the most important front-end development project in the Web’s short history. And the collaboration continues today. In fact, there have been over 1000 issues opened and closed on that repo. All because Paul Irish—who has every right to never solicit feedback, because he’s so dang smart—encouraged collaboration.

Blog Posts Should Be Like GitHub Repos

The collaboration on apps like GitHub should be exactly what happens on blog posts. The readers posting comments should read the entire article, and should offer constructive, polite criticism and suggestions, without any unnecessary negativity.

An end to negativity

If the author feels the advice is not accurate or best practice, than he should explain why. If it’s established that the point needs clarification and/or correction, then he should humbly accept this and post an update, crediting the person or persons that brought it up. Personally, I’ve seen too many posts where the author doesn’t make corrections, even when clear technical or factual errors are pointed out.

This doesn’t mean that “majority rules”—that would be ridiculous, and would probably cause more problems than it solves (particularly in matters of opinion, where often there are no hard-and-fast rules).

But if it’s a technical matter, then the author has the responsibility to make updates and keep the information fresh, practical, and relevant. This is especially important if readers are finding the article via search. The “copy-and-paste-but-don’t-read” mentality is common among developers looking for quick solutions. We all face tight budgets and even tighter deadlines, so the last thing we want to do is verify a piece of code’s quality by reading a 900-word accompanying article along with 50+ comments.

If you notice a lot of search traffic coming in for older articles on your website, that might very well be incentive to update those older posts, and ensure you’re not promoting something that you no longer believe is accurate or best practice. And this has a twofold benefit: It will get you even more traffic, and your readers will have accurate information that they can trust.

So let’s do our best to imitate collaborative communities like those found on GitHub and StackOverflow, and continue making progress by correcting our errors. This will help all of us overcome the fears inherent in publishing what we learn.

The “TL;DR” Conclusion

If you don’t read this entire post, or if you take nothing else away from it, then just remember these points:

  • When you learn something, write about it, and don’t do it just to make money off it.
  • Don’t be afraid to make mistakes.
  • Teaching others will help you learn.
  • Encourage collaboration by allowing a free flow of constructive comments.
  • If you make a mistake, fix it.

I think this is a winning strategy for all those who are involved in design or development blogging, as well as tutorial writing.

When we’re willing to put ourselves out there, listen to what our peers have to say, and improve as needed, we will become better developers, and will help each other solve design and development problems in a more effective manner.

As this article suggests, your voice is just as important in this discussion. What do you think? Are you motivated to publish what you learn? Do you think collaboration and constructive feedback is an important part of moving the Web forward? We’d love to hear your thoughts.

Image used on frontpage: opensourceway.

(il) (jvb)

© Louis Lazaris for Smashing Magazine, 2012.

0
Your rating: None