Vector is now Happy Cog

Read more about this exciting transition here

Single-page JavaScript Apps and Debugging

Khaliq Gant
07.07.15
Single-page JavaScript Apps and Debugging
Khaliq Gant
07.07.15

Fireclay Tile, one of our clients, is the leading U.S. recycled ceramic and 100% recycled glass tile manufacturer. They make beautiful products and offer a wide assortment of customization and purchase options. To help showcase this, they have a Gallery section of the website that shows their products being used in different rooms, using different materials, styles, patterns, and colors.

We were tasked with a refresh of this section of the site with the main emphasis being on speed and fast load times. This section would essentially be a single page app within the larger website. They wanted users to be able to apply the available filters (rooms, materials, styles, patterns, and colors) and have the appropriate content load in without page refreshes. They also wanted the content changes to correspond to a change in push state so the user could go back and forth between the content as if the page was reloading.

Requirements:

  • No page reloads between filter clicks
  • Push state manipulation
  • Filters within the same family should replace the current filter
  • Filters outside a given family should be appended as an additional filter

The question I usually ask when faced with a task is, “what libraries exist out there already, which can save me time to accomplish this task?”. There are no shortage of frameworks that could have been used for this (e.g. Backbone, Angular, or React) but the project currently doesn’t use any of those frameworks and it didn’t make sense at the time to bring in a framework for just this one section.

I had previously heard of History.js and it seemed like a great option given its extensive API and browser support. In addition, given the need to swap out family filters, URI.js seemed like a great fit to help break out the URL segments and deal with the logic.

Now that I knew what my dependencies would be I started to lay out the structure of the JavaScript.

I knew this JavaScript would have a lot of functionality and need a lot of debugging so I decided to make the main javascript object and an Immediately Invoked Function Expression (IIFE). At its very start it would look like this:

This way I could access the Gallery object from the console and give myself an API in the console to make it easier to test and debug. I also would make sure that my onClick listeners would not be doing the heavy lifting but rather I had functions that would handle all the logic. This would help make the app more testable and allow me to mimic clicks from the console instead of actually clicking around. For example:

This is the code that controls the actual clicking of a filter action. We’re first looping through all the pushLinks, adding an onClick listener to each, grabbing the element, and then passing it to functions that handle the rest of the logic. I’m a firm believer in handling logic in purpose-driven functions and not listeners. This allowed me to write tests using QUnit (which could be a blog post onto itself!) by passing elements into the functions of the Gallery object. Because the Gallery object is an IIFE I could just call

Another tactic that helped a great deal in following what was going on in the logic was adding in debug statements that only show in non-production environments:

The debug.status is set automatically based on the environment, so all those debug statements won’t show on production but only on my local and staging environment. That logic looks like this

This allows me to also turn the debug off in case debug statements are crowding the console.

With that structure in place, I began to add in a number of functions, used the JavaScript’s data structures and through lots of debugging and sweat and tears (ok -- mostly just debugging) I reached the final stage to launch.

You can view the final product here: https://www.fireclaytile.com/gallery! This was a very fun mini single page app to build and I learned a ton of things along the way.

Back to Blog