Building the YouNow Profile App: Initial Prototype

The initial prototype implementation for the YouNow profile app was a pure jQuery, single file script. In this post, I\’ll talk about the point at which the code became unbearable and how that led to the appreciation of Backbone.js.

This post is part 2 in a series of posts about building the profile app. See part 1 here.

As stated, the initial implementation was a single script application. Let\’s take the header section of the app.

\"The

The single script might start to look like the following:

(function (window, $, _, Backbone) {
  if (! $) throw new Error('jquery not found');
  // More error throwing here for missing libs

  // The meat of the DOM interaction logic
  // happens on DOM ready 
  $(function () {
    // The YouNow logo is an <img> tag within 
    // an <a> tag, so there's no need for JS
    
    // On the keypress within the search bar
      // If the keypress was the enter key, 
      // then it's time to search
        // Grab search term
        // fire off ajax call for data
        // For each response,
          // Populate a template (or clone and 
          // set the html for some existing DOM element) with the data
        
          // Add the result to the results <ul> or other
        // Show the search results
    
    // On click of the search icon (magnifiying glass)
      // Repeat the above (preferably call a function
      // that does the above.

    // On click of the Facebook Login button
      // Trigger auth through Facebook
      // Then through YouNow
 
      // Populate the user badge with the 
      // logged in user's data
      
      // Show the user badge
        
  });
})(window, window.jQuery, window._, window.Backbone);

I\’ve commented the bulk of the DOM logic for the header. There\’s a lot more of course, since the user badge has logic in its menu as well:

\"YouNow

By now, this little script is already getting big. Sure, you can use fancy comments to block things off:

(function (window, $, _, Backbone) {
  if (! $) throw new Error('jquery not found');
  // More error throwing here for missing libs

  // The meat of the DOM interaction logic
  // happens on DOM ready 
  $(function () {
    // The YouNow logo is an <img> tag within 
    // an <a> tag, so there's no need for JS
    
    ////////////////////
    // SEARCH STUFF
    ////////////////////
    // On the keypress within the search bar
      // If the keypress was the enter key, 
      // then it's time to search
        // Grab search term
        // fire off ajax call for data
        // For each response,
          // Populate a template (or clone and 
          // set the html for some existing DOM element) with the data
        
          // Add the result to the results <ul> or other
        // Show the search results
    
    // On click of the search icon (magnifiying glass)
      // Repeat the above (preferably call a function
      // that does the above.

    ////////////////////
    // LOGIN STUFF
    ////////////////////
    
    // Click the facebook login button...

  });
})(window, window.jQuery, window._, window.Backbone);

But that only gets you so far. I mean, just look at the Bio section:

\"Profile

\"Non-owner

There are two states: owner and non-owner. Both states have logic about the description, social networking buttons, etc. The point is, this little script will very quickly become big and complicated. Having the foresight to prevent the single-script disaster is important to reassess your path and explore better alternatives.

Sure, you can make it work with some persistence. However, the biggest worry is that without a clear separation of the logical portions of the app, you run the risk of increased and unnecessary coupling. This means that you\’re more likely to have multiple logical portions interacting with each other (sometimes depending on each other) a bit too closely.

There had to be a better way. What I really wanted was a way to say that there\’s a main div that represents the header. There\’s also a lot of logic about the parts of this header. This header logic shouldn\’t know or touch the logic for the Bio section. I needed a way of separating out these portions in an organized fashion.

Solution 1: So I thought about breaking off chunks of logic into separate files – each with its own dom ready callback. I\’d then have to worry about the directory structure about all of these pieces and fudge together my own ad-hoc framework for organizing this stuff. I could then have a ton of synchronous script tags that dictate the execution order of these pieces.

I\’ve done this in past projects (in Matlab most notably – where there\’s a directory based build/linking system) and it was a disaster. It was hard to have the foresight to predict just how large the project was going to be and the directory structure went to hell after the first 10 scripts. I didn\’t want to repeat the mistake with this javascript app, so I looked for a more established paradigm.

Solution 2: Backbone.js came to mind, but I was reluctant to use it on this high-priority project due to the fact that I couldn\’t seem to wrap my head around its use case.

After reading a dozen introductory articles, Backbone\’s Views really seemed to capture the separation of logic that I was looking for. However, I didn\’t want or understand any of the models and collections stuff. I still couldn\’t see where they fit in.

In the next post, I\’ll talk about using only Backbone Views for the second phase of the prototype.