Chapter 1. Writing Client Side Apps (Without Backbone)

Before jumping into Backbone.js development, let’s take a stroll through life without it. This is not meant to serve as a straw man argument so that in the end, we can jump up and say "look how awesome Backbone.js is!" To be sure, Backbone.js is awesome, but this exercise is meant to give you an idea of where Backbone provides structure. Once we have made it through this exercise, we will be left with a number of questions as to what the next steps should be. Without backbone, these questions would be left to us to answer.

For most of the book, we are going to be discussing Backbone in relationship to a Calendaring application. Here, we will try to get a month view up and running using nothing but server-side code and jQuery. Surely we can do this—our forefathers have been doing this kind of thing for dozens of months.

For our purposes, let’s assume that the server is responsible for drawing the HTML of the calendar itself, while the client must make a call to a web service to load appointment for that calendar. Sure, this is a conceit, but it is a conceit born of a thousand implementations in the wild.

This is not news, but working with dates in Javascript is not pleasant. We will keep it to a minimum, in part by using the ISO 8601 date format [5]. ISO 8601 date/times take the form of "YYYY-MM-DD HH:MM:SS TZ" [6]. The date that the first edition of this book was published can be represented as "2011-11-30".

The brilliant simplicity of ISO 8601 is that anyone can read it—even Americans who tend to represent date in nonsensical order. There is no doubt that 2011-11-12 represents the 12th of November, whereas Americans think that 12/11/2011 is the 11th of December, the civilized world know this to be the 12th day of the 11th month of 2011. Reading dates when the units increase or decrease from left-to-right just makes sense.

It even makes sense to a machine since, although "2011-11-12" and "2011-11-30" are strings, they can still be compared by any programming language. Machines simply compare the two as strings. Since the "2" and "2" are the same, it compares the next two characters in the string (both "0"). Eventually, the "3" and "1" are reached in the days of the month place. Since the character "3" is greater than the character "1", the following would be true regardless of language: "2011-11-30" > "2011-11-12".

Armed with that knowledge, we make the ID element of the table cells ISO 8601 dates, corresponding to the date that the cell represents.

<table>
  <tr>
    <th>S</th><th>M</th><th>T</th><th>W</th>
      <th>T</th><th>F</th><th>S</th>
  </tr>
  <tr>
    <td id="2012-01-01"><span class="day-of-month">1</span></td>
    <td id="2012-01-02"><span class="day-of-month">2</span></td>
    <td id="2012-01-03"><span class="day-of-month">3</span></td>
    <td id="2012-01-04"><span class="day-of-month">4</span></td>
    <td id="2012-01-05"><span class="day-of-month">5</span></td>
    <td id="2012-01-06"><span class="day-of-month">6</span></td>
    <td id="2012-01-07"><span class="day-of-month">7</span></td>
  </tr>
  <tr><!-- ... --></tr>
  <tr><!-- ... --></tr>
  <tr><!-- ... --></tr>
  <tr><!-- ... --></tr>
</table>

That HTML might generate a calendar that displays something like this in a browser:

January 2012

So far we have nothing more than a static calendar page. To make things a little more interesting, we add a jQuery AJAX request to the backend asking for all appointments in January:

  $(function() {
    $.getJSON('/appointments', function(data) {
      $.each(data.rows, function(i, rec) { add_apppointment(rec) });
    });
  });

That request of the /appointments resource will return JSON that includes a rows attribute. For each record in the list of rows, we want to add a corresponding appointment to the the calendar.

{"total_rows":2,"offset":0,"rows":[
  {"id":          "appt-1",
   "startDate":   "2012-01-01",
   "title":       "Recover from Hangover",
   "description": "Hair of the dog that bit you."},
  {"id":          "appt-2",
   "startDate":   "2012-01-02",
   "title":       "Quit drinking",
   "description": "No really, I mean it this year"}
]}

The add_appointment function need not be anything fancy if we simply want the appointment to display. Something along the lines of the following will suffice:

function add_appointment(appointment) {
  var date = appointment.startDate,
      title = appointment.title,
      description = appointment.description;

  $('#' + date).append(
    '<span title="' + description + '">' +
      title +
    '</span>'
  );
}

Do you see the ISO 8601 trick in there? The startDate attribute is represented as an ISO 8601 date (e.g. "2012-01-01"). The cells in our calendar <table> also have IDs that correspond to the ISO 8601 date:

  <tr>
    <td id="2012-01-01"><span class="day-of-month">1</span></td>
    <!-- ... -->
  </tr>

Thus, by appending the appointment HTML to $('#' + date), we are really appending to $('#2012-01-01') or the date cell for New Year’s day. Simple clever [7], eh?

Using this strategy, we could fetch 3 years worth of appointments from the backend and run each through the add_appointment function. An appointment from New Year’s Day 2010 would not be appended to the calendar because there is no calendar table cell with an ID of $('#2010-01-10'). That jQuery selector would produce an empty wrapped set, which results in no change.

The authors have been using a similar technique since the 1900s to great effect. For more than 10 years, it has been possible to do something like this and we did not need any fancy Javascript MVC framework.

So why do we need one now?

The answer to that question is what comes next. As in "What comes next in my calendar application?" Perhaps the user needs to move appointments between dates. Or maybe add new appointments / delete old ones. Regardless of what comes next, we are going to need to answer how. And how is the realm of Backbone.js.

Sure we might continue coming up with clever hacks like the ISO 8601 trick for our calendar. But with each clever hack, we risk making the code harder to approach for the next developer.

How do you future proof? How can you be sure that your approach will be understood by the next developer? How can you know that today’s simple cleverness will still be easy to read in 3 months?

The answer is to not choose. Rather, let Backbone show you the way.

And that is where we begin in the next chapter…



[6] The official ISO 8601 representation of a datetime includes a T in between the date and the time (2011-11-30T23:59:59). We prefer omitting the T to aid in human readability without degrading machine parsing (2011-11-30 23:59:59)

[7] as opposed to clever clever which is always a bad idea