---
title: Why your Javascript apps need more structure
teaser: 'We describe a set of best practices that make Javascript apps easier to develop
  and maintain.

  '
tags: javascript,new bamboo,web
author: Max Williams
published_on: 2010-01-29
---

_This post was originally published on the New Bamboo blog, before [New Bamboo
joined thoughtbot in London][new-bamboo-thoughtbot]._

---

There are several aspects to building javascript UIs, and you need to do a bit
of planning beforehand if you want them to be successful. **2010 is set to be
the year of Javascript's ascendancy**, and you can't ignore it. You also need to
start using it properly (if you aren't already). We have evolved beyond the
level of chucking event handlers inline in views and it is not possible to just
hope for the best as things get more complicated.

**I have divided this up into a set of best practices which I try to follow:**

* Adopt a structure early (MVC)
* Think about models properly
* Control flow in a declarative way (use Sammy)
* Use views to encapsulate the logic for different parts of your application
* Communicate between 'layers' via custom events

Another thing before diving into this. Think carefully about the target users.
The use-cases I am exploring generally refer to **apps** rather than
**websites**. Does your app need SEO? Do visually impaired people need to use
it? Are people with "not-so-smart" phones going to be a concern? If any of these
are important, make sure you **don't** build an entirely JS UI, and instead
build HTML which can degrade gracefully using normal http requests.

I have recently been making applications with Canvas and Sockets, and can't
necessarily rely on the server to generate html for me. Some of the following is
based on these assumptions, and I don't believe that everything you build should
have this much structure.

I will however attempt to lay out what I see as a new structure for JS
applications. If you're keen to know what this can look like, see [this code
sample] from the [demo app].

It is also worth noting that I am not trying to provoke a flame war here, but
rather relaying recent experience. People may disagree, and I'm keen to hear
other opinions.

## Adopt a structure

You can usually get away with slowly increasing the complexity of your JS
application until you need to refactor, but it is usually best to start off with
a basic structure first.

**I am going to suggest adopting the MVC pattern which has been made famous by
Ruby on Rails** in webby circles (though has existed elsewhere for years). It is
a good pattern, and the ideas which make it good for servers can also be applied
to GUI programming.

Several JS frameworks have attempted to give JS apps structure, but I have never
really been taken by them. I have the following constraints when choosing one:

* it has to be solid, yet not overly complex
* the code needs to feel like Javascript, not some port of a Java beast
* the parts need to be understandable, and ideally interchangeable
* using existing code beats writing everything from scratch

Sproutcore and Capuccino stop the code feeling like Javascript anymore, and GWT
is too linked to Java backends.

There are also some more lightweight frameworks such as Javascript-mvc, which
wasn't quite right for me. [The Kiwi framework] came the closest to what I
wanted, and served as a bit of an inspiration for me. In my case, it still
wasn't quite right though, hence taking a more polyglot approach.

The primary things to plan are the following:

* **Models** define the domain objects in your application and can be synced
  with the server via Ajax or other methods. They often map to database tables,
  but you shouldn't be constrained by this. If you are using REST, hooking them
  up with your app should be a doddle.
* **Views** represent parts of your <abbr title="Graphical User Interface">GUI</abbr>
  which you can interact with. They are fed by data, and need to respond to
  changes in the data.
* **Controllers** are the intermediaries between model data and the GUI elements
  which control them. In a JS app, your controllers manage the changing _state_
  of the views as a whole.

I tend to create directories for these such as /lib/views and lib/models.
Controllers are different and (as I will explain below) sit in a routes.js file
which holds all my Sammy routes.

Since a UI maintains state - unlike most web applications - you can then use
events to communicate between the layers.

## Models

You need to think about the **Models** in your app both on the level of the
individual _instances_, and as _collections_ of instances. The reason these
collection objects are needed as well as model objects is because these act as
factories. Usually (e.g. in Ruby) this would be taken care of by the class,
which itself is an object, but javascript doesn't really have classes as such,
so you need a collection object to take its place.

These data sources are used by **Views** to, for example, populate a list of
people in your account. Additionally these individual instances will have come
from rows in your database, and will therefore need to be created and updated.

Our very own [Mr Pickles] has recently been working on a library to deal with
this, which he **promises** to blog about shortly. I won't therefore go into
much detail on it, and will be using more basic examples in my examples.

## Views

There is no definitive way to represent views in a JS app, but I tend to make a
class for them, and pass in a DOM element which exists on the page. I might
therefore have objects similar to the following:

```javascript
var ProjectPicker = function(elem, projects) {
 var elem = elem;
 var projects = projects;

 var draw = function(){
   for (i in projects){
     elem.append('&lt;p&gt;'+project.name+'&lt;/p&gt;')
   }
 };

 draw();
}
```

These views are initialised on page load, passing in the data which they might
need to render, eg:

```javascript
var project_picker = new ProjectPicker($('#project_picker'), projects);
```

If the collection of 'projects' in your app changes, a 'redraw' method can be
created which uses the project list for input. There are many advantages to
using a system like this, as *View* objects can handle the manipulation of their
particular bit of the DOM in response to changes in your datasets. More about
this below in the Events section.

While I have simply injected HTML into the page as a string, there are several
better techniques for doing this. Many templating languages have been created,
such as the one included with Sammy. Personally, I like to replicate  html which
exists in the HTML, and let the server do it in one place. What is really bad is
when you emulate html created by the server in your JS, and introduce the
possibility of inconsistencies.

I am also not really fond of servers sending little bits of HTML to update the
page (as is sometimes popular with RJS and the like), and believe that a JS app
be feed data which it manipulates itself.

## Controllers

First off, use [Sammy]. It is really awesome, and allows you to reach new
heights of declarative page state changes.

If you want to show a form to create a new project, make a link to
`#/projects/new` which tells your "new project" *View* to show itself. In this
example I am just manipulating the <abbr title="Document Object
Model">DOM</abbr> directly, but you could go via your views, or trigger events:

```javascript
get('#/projects/new', function() { with(this) {
  $('#project_form').show();
}});
```

The data from this form is posted to '#/projects', where you handle your data
syncronisation, and then update your views based on the results.

```javascript
post('#/projects', function() { with(this) {
  Projects.create( { name: params['name'] } )
  redirect('#/')
}});
```

This is immensely powerful, and I have not done justice to it here. I have
written more on a [separate post about sammy][sammy state].

## Custom Events

These are really the heart of building great extensible UIs. This means
utilising the Observer pattern in your objects. I also like to think of it in
pubsub terms: a custom event has 2 parts, the trigger (publisher), and the
events which are bound to it (subscribers).

Create a convention for events which you are going to stick to. I like to link
them to my model names. Hence:

```javascript
$().trigger('Project-create', [new_project])
```

might be bound to this in my project list view:

```javascript
var ProjectPicker = function(elem, projects) {
 ...

 var add_project = function(evt, project){
   elem.append('&lt;p&gt;'+ project.name + '&lt;/p&gt;')
 }

 // EVENTS
 $().bind('Project-create', add_project)
}
```

You often need to cascade events, so that the listener for 1 event makes a
change and then publishes a new event. It is cool.

When you use or create a decent library for syncing your **Models** via Ajax,
you can add callbacks based on your conventions so that a
successful/unsuccessful request to your server triggers the following:

```javascript
//Create:

'Object-create', object
'Object-create-error', object.errors

//Update:

'Object-update', object
'Object-update-error', object.errors

//Destroy:

'Object-destroy', object
'Object-destroy-error', object.errors
```

## A brief illustration of these principles

I have made a little [demo app], to show how these principles can be used. It
doesn't use Ajax, but shows you the points where it could be added. This app is
far from perfect, and I don't want to suggest that the way I chose is the only
one. But I think the code shows what I'm trying to get at.

[demo app]: https://bamboo-blog-assets.s3.amazonaws.com/mvc_demo.html
[Mr Pickles]: https://twitter.com/benpickles
[new-bamboo-thoughtbot]: https://thoughtbot.com/blog/new-bamboo-joins-thoughtbot-in-london
[sammy state]: https://thoughtbot.com/blog/using-sammy-for-changing-page-state
[Sammy]: http://code.quirkey.com/sammy/
[The Kiwi framework]: http://github.com/rpbertp13/kiwi
[this code sample]: http://gist.github.com/287082
