Tumgik
jsondata · 12 years
Text
BackboneBlog: A Reference Project
To help round out my blog series on Backbone, I wrote a little reference app a few months back to help me keep my bearings whilst building large scale client applications. At the time, I was contracting with a local startup that was building a fairly complex client/server web app. The front end was all written in Backbone (and the back end in Java/Spring). On this project, our dev team was distributed. Half of our team was working in a remote location, with the other half located in Scottsdale. As I became more involved in the project, I began to realize that we needed a bit more cohesion in our client side coding efforts. I think I was a little late to the game on that, but I think (hope) some found it helpful. **Anyway, here it is: [BackboneBlog](https://github.com/JasonOffutt/BackboneBlog).** It's a little out of date at this point. I need to update the Require.js implementation to the latest version. That'll allow me to cut more unnecessary code via the (lib).require.js module shims for the projects that don't support AMD, along with a few other odds and ends. I hope you find it helpful. Feel free to fork it and play around with it. If you end up finding any bugs or adding anything to it, please shoot me a pull request. :)
1 note · View note
jsondata · 12 years
Text
Event aggregation with Backbone
This is the sixth post in my blog series on Backbone.js. If you haven't had a chance yet, make sure to catch up on the first 5: 1. [Hey, check out my Backbone](http://jsondata.tumblr.com/post/25488008705/backbone-1) 2. [Aligning my Backbone](http://jsondata.tumblr.com/post/25552904859/backbone-2) 3. [Backbone Routers Are Configuration](http://jsondata.tumblr.com/post/26508172926/backbone-3) 4. [Grokking Backbone Views](http://jsondata.tumblr.com/post/26860395853/backbone-4) 5. [Async Template Loading with Backbone](http://jsondata.tumblr.com/post/30043887057/backbone-5) In my second post I talked about how I employ the [MVP design pattern](http://en.wikipedia.org/wiki/Model-view-presenter) to keep components of my JavaScript apps nicely decoupled. Interestingly, since that post, there have been some rumblings on the interwebs calling this pattern ['MOVE'](http://cirw.in/blog/time-to-move-on). I think you'll see it popping up more and more as it gains momentum. In my first post, I also mentioned that when you look at Backbone through an "MVC lense", initially people often make a few incorrect assumptions on how the app should work. This is often based on their understanding of how a server-side MVC app functions. It certainly was in my case. In this post I'm going to cover how this approach differs from the common understanding of server-side MVC. **Getting Pub/Sub** One piece of knowledge hit me last fall as I was writing the Facebook authentication app (in Backbone/CoffeeScript) for the latest version of CentralAZ.com. Here it is: **JavaScript apps written on the client are not stateless**. If you've written lots of client apps in your career, then this probably isn't a huge surprise to you, but this little tidbit of knowledge totally blew my mind. My focus had been on the server for so long, that I projected a lot of what I knew about ASP.NET MVC and Rails onto Backbone. [This post by Derek Bailey](http://lostechies.com/derickbailey/2011/08/03/stop-using-backbone-as-if-it-were-a-stateless-web-server/) really drove that point home for me. **In a Backbone application, the model is a representation of the current application state.**
mind === 'blown' > true
In Backbone, the preferred method of cross-communication between app components or modules is to use the [Observer pattern](http://en.wikipedia.org/wiki/Observer_pattern), also commonly referred to as "pub/sub". In Backbone, you get a very nice way implementing this pattern via extending Backbone.Events. This allows different components of an app to send messages or listen for messages being broadcast by an event aggrigator without having to know where those events are coming from. **How does that work?** To illustrate, we'll assume each JS module lives in its own file and that the app is composed when the page loads via [AMD (Asyncronous Module Definition)](http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) in [Require.js](http://requirejs.org/). It's not important to fully grok AMD to understand how the following code samples work together, **the important thing to understand, though, is that each of these JS snippets represent separate JS files.** They're fully encapsulated and know nothing of each other, beyond the dependencies they request in the first parameter of the `define()` function call.
// Define a module to return an event aggrigator object extended from Backbone.Events. // Let's call this events.js. define(['underscore', 'backbone'], function (_, Backbone) { return _.extend({}, Backbone.Events); });
Let's pretend we have an app that allows a user to authenticate and view their own personal information. In this sample app, we'll be listening for 2 different events. We want to listen for an event that signifies that a user intends to log out of their account. But we also want to know when the user has actually been logged out by the server. In Backbone apps, it's considered good practice to namespace your events by object or model type. An event name can be any string value, but in order to keep things organized and easy to understand, we'll use this convention:
events.trigger('object:property'); // or events.trigger('object:action');
OK, so now that we've got our event aggregation object, we'll listen for the `user:loggedOut` event in the `initialize` method of our router. When a user clicks on a "logout" button, the user should be redirected to the home page once the server successfully logs them out. We'll take a *pessmistic* approach to this event, meaning that we'll wait to make sure "logout" actually happened on the server before we redirect.
// Defining a router module, called router.js define(['backbone', 'events', 'presenter'], function (Backbone, events, Presenter) { var router = Backbone.Router.extend({ routes: { '': 'index', 'myprofile': 'userProfile' }, initialize: function (options) { // Wiring up the presenter just like we did in a previous post... this.presenter = new Presenter(options); // _.bindAll is important here, because `this` will not be the current // instance of our router when it the events bound below get triggered. _.bindAll(this); // Here's the magic that binds a function to the `user:loggedOut` event events.on('user:loggedOut', this.onLogout); }, // Here's our event handler. It accepts a user model object, but we're not // going to use it here... onLogout: function (user) { // Call Backbone.Router.navigate here to tell our router to update the // URL and log browser history, sending the user to the home page. The // empty string in this call corresponds to the empty string in the // routes declaration above. this.navigate('', true); }, // Route handler definitions that get bound based on routes defined above index: function () { this.presenter.showIndex(); }, userProfile: function () { this.presenter.showUserProfile(); } }); return router; });
Additionally, we'll have a view called `authenticationView.js` that listens for the `user:loggedOut` as well, that will fire when the user is successfully logged out by the server.
// Defining a authentication view module called authenticationView.js define(['backbone', 'events', 'templateManager'], function (Backbone, events, TemplateManager) { var view = Backbone.View.extend({ template: 'userAuthentication', className: 'user-authentication', initialize: function (options) { this.model = options.model; _.bindAll(this); // When the user logs out, we just want to re-render this view events.on('user:loggedOut', this.render); }, // Nothing extra special going on in our view's render method. Our template will // check the model's `isAuthenticated` flag to see if the user is currently // logged in. render: function () { var that = this; TemplateManager.get(this.template, function (tmp) { var html = tmp(that.model.toJSON()); that.$el.html(html); that.rendering(); }); return this; }, // In a previous post I covered having your views clean up after // themselves to avoid memory leaks. Here's a good example of this // in practice. In `onClose`, we'll unsubscribe from `user:loggedOut` onClose: function () { events.off('user:loggedOut'); } }); return view; });
Here's what our corresponding Handlebars client-side template would look like. We'll call it `userAuthentication.html`.
{{#if isAuthenticated}} <a href="#">Howdy {{name}}!</a> {{else}} <a href="#">Log In</a> {{/if}}
We'll also have a second view that has a "Log Out" button that will fire the `user:loggingOut` event to get things kicked off.
// Defining our userProfile.js module. define(['backbone', 'events', 'templateManager'], function (Backbone, events, TemplateManager) { var view = Backbone.View.extend({ template: 'userProfile', className: 'user-profile', events: { 'click #log-out', 'logoutClicked' }, initialize: function (options) { this.model = options.model; _.bindAll(this); }, render: function () { var that = this; TemplateManager.get(this.template, function (tmp) { var html = tmp(that.model.toJSON()); that.$el.html(html); that.rendering(); }); return this; }, logoutClicked: function () { // Fire the `user:loggingOut` event to kick things off. Make sure to pass // along a reference of the current user. events.trigger('user:loggingOut', this.model); return false; } }); return view; });
You might be asking yourself, *"That's great, but how does the user actually get logged out?"* Great question. We'll just wire up another listener on the presenter to tell the model to log itself out.
// For posterity, here's what our presenter.js would look like. define(['events', 'userModel' 'indexView', 'userProfileView'], function (events, UserModel, IndexView, UserProfileView) { var Presenter = function (options) { this.model = options.model || new UserModel(); _.bindAll(this); // We'll set up a handler here to listen for `user:loggingOut` events.on('user:loggingOut', this.onLogout); }; Presenter.prototype.showView = function (view) { if (this.currentView) { this.currentView.close(); } this.currentView = view; $('#container').append(this.currentView.render().$el); }; Presenter.prototype.showIndex = function () { var view = new IndexView({ model: this.model }); this.showView(view); }; Presenter.prototype.showUserProfile = function () { var view = new UserProfileView({ model: this.model }); this.showView(view); }; // Here's our handler for `user:loggingOut`. We'll have the user model call logout // on itself. Presenter.prototype.onLogout = function (user) { var promise = user.logout(); // `user.logout` returns a jQuery deferred, so we can bind a handler to trigger // the `user:loggedOut` event when the ajax call completes successfully. promise.done(function () { events.trigger('user:loggedOut', user); }); }; return Presenter; });
Finally, to complete the story, we'll wire up our user model so it knows how to to log itself out.
// Defining a module for our user model called user.js define(['backbone', 'events'], function (Backbone, events) { var model = Backbone.Model.extend({ initialize: function (options) { _.bindAll(this); }, logout: function () { var that = this, promise = $.trafficCop({ type: 'POST', url: '/user/logout', data: this.toJSON() }); // Bind a callback to our promise to set the `isAuthenticated` flag // to `false` when logout completes successfully. promise.done(function () { that.set({ isAuthenticated: false }, { silent: true }); }); return promise; } }); return model; });
**But why not just use jQuery's built in event pool?** It's true that jQuery has its own version of Backbone.Events that looks the same, and is implemented, in much the same way. The Backbone team, I believe, decided to roll their own version for two good reasons: 1. If I understand correctly, when Backbone was first being written, jQuery's event pooling employed a DOM-based eventing system (e.g. - `document.addEventListener`, etc). Since then, jQuery has moved to an object-based eventing system similar to Bacbkone's. 2. In order to keep the dependency tree light, Backbone's only dependency is Underscore. There's not a hard dependency on jQuery (nor should there be). Using jQuery's eventing system would require a hard dependency on jQuery. **What's with `_.bindAll` being called everywhere?** A lot of people new to Backbone may not be too cozy with Underscore (yet). Basically, calling `_.bindAll(this)` will ensure that all methods of the object passed in will have the correct context of `this` bound to its [calling context](http://www.bennadel.com/blog/2265-Changing-The-Execution-Context-Of-JavaScript-Functions-Using-Call-And-Apply-.htm). Doing this basically guarantees that `this` will represent the current object in scope, rather than `window`, a DOM element, or some other less predictable thing. That's what I've got for now. Does your mind hurt yet? When you recover, do you think you might use this approach in your apps? Let me know if in the comments below.
1 note · View note
jsondata · 12 years
Text
Async Template Loading With Backbone
This is my fifth post in a series on Backbone.js. Here are the first 4 in case you need to get caught up: 1. [Hey, check out my Backbone](http://jsondata.tumblr.com/post/25488008705/backbone-1) 2. [Aligning my Backbone](http://jsondata.tumblr.com/post/25552904859/backbone-2) 3. [Backbone Routers Are Configuration](http://jsondata.tumblr.com/post/26508172926/backbone-3) 4. [Grokking Backbone Views](http://jsondata.tumblr.com/post/26860395853/backbone-4) In my previous post, I dug into the guts of how Backbone Views work, how to render them using client-side templating, and extending off of Backbone.View's prototype. This post is going to build off of the previous one. Today, we're going to talk about lazy-loading your client-side template HTML files asynchronously, caching, pre-compiling them, and why these are usually all good ideas. But before we get into the *Why's* and *How's*, I want to talk about the *Why Not's*. **When async templates don't make sense** I generally subscribe to [Jeff Atwood's](http://codinghorror.com) idea that **the best code is no code**. Jeff probably didn't originate that, but I've read it in several of his blog posts, and it has stuck with me throughout my career. So when does loading your templates asynchronously via AJAX, pre-compiling and caching them not make sense? When you really want to avoid unnecessary code. You can just as easily stick your templates inside inline `` tags, hang them off of properties on your views, or pre-load them with an [Asynchronous Module Definition (AMD)](http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition) framework like [Require.js](http://requirejs.org). Additionally, in the event that you're writing an app that requires some sort of offline support, lazy loading anything from the server isn't really an option. You really need certain features at your fingertips as soon as the page loads. I know that's kind of a no-brainer, but it's definitely worth mentioning. **So why would I use this then?** *Because it's faster!* Lazy loading allows you to only load the templates that your application needs at any given time. This helps lighten the initial load of your application's content. It also helps reduce the amount of HTTP requests initially sent back to the server as the page loads if they're pre-loaded with something like Require.js. You can also pre-compile your templates to optimize their performance when you lazy load them. While pre-compilation isn't unique to this approach of template loading, it *does* give you a nice unified place to put this functionality. Finally, this approach also give you a single place to manage initialization of any partials your app might need to care about. It allows you to encapsulate how you actually render your templates. You can use whatever templating library you like (Underscore, Mustache, Handlebars, etc). Now you can easily change this implementation in a single place, rather than sprinkling this concern throughout your views. **The Usage** In [my last post](http://jsondata.tumblr.com/post/26860395853/backbone-4), I showed some examples of how Backbone Views can render their content from a hard-coded string stuffed in a `template` property on the View object. You'll also often see templates stored as HTML fragments inside `<script type="text/html">` blocks that can be selected by ID from jQuery. Both of these are nice for quick and dirty implementations. However, I typically like to store my templates in separate HTML files located in a `/templates` folder just to keep things organized a little better. Here's what our usage would look like if we refactored the previous code example to use a `TemplateManager` object to lazy-load our templates for us. *FooView.js* <pre> var FooView = Backbone.View.extend({ tagName: 'li', className: 'foo', // `template` is now the name of a file (sans extension) instead of the HTML // fragment itself template: 'foo-list-item', events: { 'click .fooButton': 'fooClicked' }, initialize: function (options) { this.model = options.model; this.model.on('change', this.render); _.bindAll(this); }, render: function () { var that = this; // Note that we're still doing much the same thing to create the HTML content // and stuff it into the DOM, but we're doing it inside this callback. TemplateManager.get(this.template, function (tmp) { var html = tmp(that.model.toJSON()); that.$el.html(html); }); // And we're still returning `this`, but it's highly likely that our `render` // method will return *before* the HTML has been placed into the DOM. return this; }, fooClicked: function (e) { alert('ouch!'); return false; }, }); **Remember how I talked earlier about rendering templates asynchronously?** Yep. That's what's happening here. Almost every time, our `view.render()` function will return *before* the HTML content is actually placed onto the page. You may ask, *"How is this possible? Why would you do it that way"*. The async nature of this approach certainly adds a bit more complexity, but it makes up for the added complexity in speed. Our app won't block execution whilst waiting for that HTTP request to finish, and when the content has been loaded, we've provided a nice callback so our View knows what to do with it when it completes. Let's look at the implementation of a `TemplateManager` to see how this works. **The Implementation** If you're a server-side coder, think of the TemplateManager as a sort of static class or object that just has a handful of utility methods or properties. *TemplateManager.js* <pre> var TemplateManager = { // Here, we're keeping an object literal around to act as a hash table, and we'll // be using it to cache each template that gets loaded from the server. templates: {}, get: function (id, callback) { // Can we find this template in the cache? if (this.templates[id]) { // Yes? OK, lets call our callback function and return. return callback(templates[id]); } // Otherwise, lets load it up. We'll build our URL based on the ID passed in. var url = '/templates/' + id + '.html', // And use a handy jQuery library called Traffic Cop to handle marshalling // requests to the server. This will prevent multiple concurrent requests // for the same resource. promise = $.trafficCop(url), that = this; // Wire up a handler for this request via jQuery's promise API promise.done(function (template) { // `template` is a string of HTML loaded via `$.ajax`. So here, we // can take the opportunity to pre-compile it for performance. When we // pre-compile a template, it returns a function that we can store in our // cache for future use. var tmp = Handlebars.compile(template); that.templates[id] = tmp; callback(tmp); }); } }; You probably noticed in the above code example my usage of `$.trafficCop`. It's a super useful jQuery plugin that acts as a proxy for `$.ajax`. It comes in really handy when you have several concurrent requests coming in for the same resource. A great example of this would be rendering a list view. Let's assume this list view might have a collection of child list item Views that require their templates to be loaded as well. TrafficCop would prevent more than one request from actually making it to the server. It stores the callbacks to each request for a resource and will call them back in the correct order. I picked it from from [Derek Bailey](http://lostechies.com/derickbailey/). Check out [the repo on GitHub](https://github.com/ifandelse/TrafficCop) for more info on TrafficCop. **Handling Partials with TemplateManager** In addition to lazy-loading templates on the fly, I also will use `TemplateManager` to pre-load and register partials when our app is initialized. <pre> var TemplateManager = { // ... // You could stash an array of well known partials that need to be rendered // and registered with your Templating engine of choice. partials: [ { name: 'fooForm', template: 'foo-form' } ], registerPartials: function (callback) { var that = this; _.each(this.partials, function (partial, index) { // As we're iterating over our partials, we can call our // existing `get` function to pre-compile and cache them. that.get(partial.template, function (tmp) { Handlebars.registerPartial(partial.name, tmp); if (index + 1 === that.partials.length) { callback(); } }); }); } }; Now when we're bootstrapping our app, we can pre-load all of our partials before starting our router. *app.js* <pre> $(function () { TemplateManager.registerPartials(function () { var router = new FooRouter({ model: someData }); Backbone.history.start(); }); }); The benefit of this is a little bit more specific, but it enables you to call partials by name in your templates to encapsulate common HTML fragments. *new-foo.html* <pre> <div class="new-foo"> <h3>Fill out the following form to create a new foo</h3> {{> fooForm}} </div> *edit-foo.html* <pre> <div class="edit-foo"> <h3>Editing foo: '{{name}}'</h3> {{> fooForm}} </div> That basically covers it. As you can probably tell from my examples, I've been using Handlebars quite a bit for my templating. So far I'm becoming a fan. It's got a good balance of functionality via partials, blocks, helpers, etc. These help keep imperative code out of your template markup. And pre-compiling helps boost performance a lot (check out [Derek Bailey's blog post](http://lostechies.com/derickbailey/2012/04/10/javascript-performance-pre-compiling-and-caching-html-templates/) on this subject for more details). It's also worth mentioning that this technique is implemented in Derek Bailey's Backbone.Marionette plugin. I haven't had a chance to kick the tires on it yet, but I've heard great things about it. So what do you guys think? Is the added speed and flexibility of async template loading worth it to you? Do you plan on using this technique in any of your single page apps?
4 notes · View notes
jsondata · 12 years
Text
Grokking Backbone Views
This is my fourth post in my series on Backbone.js. Make sure to read the first three if you haven't had a chance to check them out yet. 1. [Hey, check out my Backbone](http://jsondata.tumblr.com/post/25488008705/backbone-1) 2. [Aligning my Backbone](http://jsondata.tumblr.com/post/25552904859/backbone-2) 3. [Backbone Routers Are Configuration](http://jsondata.tumblr.com/post/26508172926/backbone-3) In my last post, I started digging into the guts of how Backbone Routers work. In this post we're going to dive into Backbone Views. In Backbone, Views take a more active role than you may be used to if you've been working with frameworks like Rails or ASP.NET MVC. On the server, Views are generally logic-lite templates. They're typically HTML markup fragments with a smattering of code blocks to handle anything that needs to be dynamic. Backbone Views, however, are all code (though mostly configuration) and contain any necessary logic for the View to render itself in the DOM and wire up any event handlers it needs to worry about. In Backbone, Views are, in many ways, like Controllers (far more than Routers are). Views serve as your app's entry point for user interaction and will be responsible for kicking off events that your apps will use to actually get things done. Backbone Views serve as a window into your Model's state for the user. **The basics** Lets start with an example of a basic View, annotated with comments of course...
var FooView = Backbone.View.extend({ // `tagName` and `className` are standard parts of Backbone.View that // are used to dynamically create the view's `el` property. tagName: 'li', className: 'foo', // `template` is an HTML fragment that will be populated with data // from the model. More on this further on in the post. template: '<strong><%= name %></strong><a href="#" class="fooButton">Click me</a>', // `events` functions as a hash table of events and function names // for a Backbone.View to map DOM events to. Think of it as the Router's // `routes` hash table for your View. events: { 'click .fooButton': 'fooClicked' }, // `initialize` is used as an entry point into the View. It functions // like a constructor. initialize: function (options) { // If your view needs to be dynamic, you'll want to pass it a model. this.model = options.model; // Here, we're listening to the `change` event on the model. Any time // the Model this View is watching changes, its `render` method will // get called, allowing the view to keep up to date with the Model state. this.model.on('change', this.render); }, // `render` dictates how the Model will be represented in the DOM. You can use // whatever methods you like to create your View's content. The most popular // way of doing so is to use a client-side templating system. render: function () { // Creating an HTML string populated with the Model our view is watching. // Here, we're using Underscore's built in `template` function, but you // can use any other templating system, or concatenate strings manually // if that's your thing. var html = _.template(this.template, this.model.toJSON()); // Inject the HTML fragment into our view's `$el` alias (more on this) // below... this.$el.html(html); // It's always good practice to return `this` from your render method // so it can be chained off of. return this; }, // Here's our click handler. If you're using jQuery, this will be a // jQuery click event. fooClicked: function (e) { alert('ouch!'); return false; }, });
So with the implementation now in context, let's take another look at how you would use this view. Remember, we're only going to be directly dealing with Views from within our Presenter. For posterity, I'll also include a basic implementation of some of the other parts so you can see how things work together.
/** * Setting up a very basic Model and Collection structure here... */ var Foo = Backbone.Model.extend({}), FooCollection = Backbone.Collection.extend({ model: Foo }); /** * Here's our presenter. Just much like the one in my second post... */ var FooPresenter = function (options) { this.fooCollection = options.model; }; FooPresenter.prototype.showView = function (view) { if (this.currentView) { // Note that we're calling `close` here. This method does not exist in //Backbone.View yet. I'll demonstrate how to add this extension method // and why it's important further along in this post. this.currentView.close(); } this.currentView = view; // Note the chaining when passing the view's `$el` to jQuery $('#container').html(this.currentView.render().$el); }; FooPresenter.prototype.showFoo = function (id) { var view = new FooView({ model: this.fooCollection.get(id) }) this.showView(view); }; /** * Our super basic Router. */ var FooRouter = Backbone.Router.extend({ routes: { 'foos/:id': 'showFoo' }, initialize: function (options) { this.presenter = new FooPresenter(options); }, showFoo: function (id) { this.presenter.showFoo(id); } }); /** * Here's our app's entry point inside a jQuery "document ready" handler */ $(function () { // Setting up some dummy data... var fooCollection = new FooCollection([ new Foo({ id: 1, name: 'foo1' }), new Foo({ id: 2, name: 'foo2' }) ]), router = new FooRouter({ model: fooCollection }); Backbone.history.start(); });
**What's the deal with `el` and `$el`?** The `el` property is the DOM element that the View is watching. Think of `el` as the representation of your View in the DOM. Every Backbone View has one, whether it's been inserted into the DOM yet or not. If the HTML element your View is supposed to know about is already on the page, you can define it explicitly using a CSS selector. The `$el` property is a jQuery (or Zepto) alias of `el` that gets created when the View is initialized. So assuming you have an HTML fragment that looks like this:
<div class="wrapper"> <section id="foo-container"></section> </div>
You could have a Backbone View that's defined like this:
var FooView = Backbone.View.extend({ el: '#foo-container', // ... });
The thing to remember is that generally, you'll want to do this when the element your View is concerned with is already present on the page. For example, if you're rendering all of your HTML on the server, or if you're trying to fit Backbone into a legacy application for a more modern twist to your UI code. If you don't define `el` explicitly, Backbone will create it for you based on the `tagName`, `className` and `id` properties you configure. If you are rendering your HTML on the fly, or fetching it from the server via AJAX later on, Backbone's View implementation will create `el` for you in memory if it's not present in the DOM. This is my preferred method of doing things, especially if I'm using a templating system in conjunction with my Views. I like to keep things as tidy as possible. So I usually like to create and remove DOM elements on the fly rather than taking the hide/show approach of toggling views. **Rendering Templates** In Backbone, you can use any templating method you want to populate your View's `el`. I've used the basic templating system that comes baked into [Underscore.js](http://underscorejs.org/) as well as [Mustache](http://mustache.github.com/) and [Handlebars](http://handlebarsjs.com/). So far, Handlebars is my favorite. The syntax is super simple (much like Mustache's), but offers a little bit more utility than Mustache alone does. The nice thing about this approach is that you can use any means necessary to populate your View's `el` container with content. If you really love concatenating strings together, knock yourself out. **How does the eventing system work?** Backbone uses a well-known hash table called `events` on the View. It works in much the same way that `routes` works on the Router. When your View is initialized, Backbone will iterate through each member of that hash table and create an event handler for it. It uses this pattern:
events: { 'eventName selector': 'methodName' }
On the left side of each item in the hash, Backbone will parse out the DOM event name and the CSS selector of the element it's delegating to. On the right hand side of the hash is the name of the View's method that will handle the event. If you're using jQuery, Backbone will use jQuery's `delegate` and `undelegate` functions to set up and tear down these events. Additionally, Backbone's View system implements two methods called `delegateEvents` and `undelegateEvents` to provide additional utility, should you ever need it. **Extending Backbone.View** Have you ever used a web app that uses a lot of JavaScript, and it just feels sluggish? Me too. It's no fault of JavaScript's that the app reacts slowly. The fault lies squarely on the shoulders of the developer. Odds are, when you run into something like this, it's because the developer is not doing a very good job of managing memory. **To be clear, JavaScript is not an unmanaged language.** It has a garbage collector. When the runtime isn't using an object, it gets eaten just like you might expect in any other managed language. The main 'gotcha' happens when you have objects loaded into memory that are associated with DOM elements. To illustrate, if you have a large array that gets created in an event handler, and say that event goes out of scope once it completes, there's no guarantee that the array will be eaten by the garbage collector right away, because the DOM element still exists on the page. This is quite a bit more prevalent in certain browsers (*cough* IE *cough*) than it is in other, more modern browsers. These issues most likely won't ruin your app. I'm sure we've all written enough nasty looking spaghetti-code JS apps to prove that it's not the end of the world if you've been guilty of this sort of thing in the past. However, it is nice to know it exists and that Backbone provides a nice way of cleaning up after yourself. It wasn't until I began writing larger scale JavaScript applications that I realized I needed to start worrying about memory management. Remember that line of code in the `FooPresenter` implementation of `showView` above, where I called `this.currentView.close()`? Backbone's View implementation does not have a `close` method. So here's how I implemented it (which I'm pretty sure I got from [Derek Bailey's blog](http://lostechies.com/derickbailey/)):
Backbone.View.prototype.close = function () { // A View's `remove` method will call `$el.remove()` to remove the View's element // from the DOM. this.remove(); // Calling `unbind` here will unbind any DOM events that the View's `el` element // or any of its children were listening for this.unbind(); // I also do a little check here to see if the current View has defined an `onClose` // method. If so, I will call it. if (typeof this.onClose === 'function') { this.onClose(); } };
Here's what a View's onClose implementation might look like:
var FooView = Backbone.View.extend({ onClose: function () { // In `close`, you can unbind any events you listened for in `initialize` this.model.off('change'); // Additionally, if your View has any child Views that it created at any point, // you can iterate over them and call `close` on each child View. _.each(this.childViews, function (view) { view.close(); }); } // ... });
So that provides a way of keeping your memory footprint nice and small whilst helping keep the DOM free of clutter, and it does so in a way that you can use across any Backbone View. I find myself adding this to almost every Backbone project that I work on. I hope this post helped you grok Backbone's View system more fully. If you have any questions or advice, please feel free to leave me a comment!
1 note · View note
jsondata · 12 years
Text
Backbone Routers Are Configuration
This is the third post in my series on Backbone.js Make sure to catch up on the first two if you haven't already. 1. [Hey, check out my Backbone](http://jsondata.tumblr.com/post/25488008705/backbone-1) 2. [Aligning my Backbone](http://jsondata.tumblr.com/post/25552904859/backbone-2) In my last post I covered how using the [Model View Presenter design pattern](http://en.wikipedia.org/wiki/Model-view-presenter) will help you write cleaner apps without cluttering your Routers with unnecessary application or presentation logic. In this post, I'm going to get into the guts of the Backbone Router object, demonstrate how I've used it, and hopefully dispel some misunderstandings about its use. **Routers are really just configuration files** When we look at other MVC-like frameworks (especially on the server side), they all use a router to control how incoming URLs get mapped to the appropriate controller action method. Backbone.js is no different in that respect. Let's consider a couple examples from Backbone's server-side cousins. In ASP.NET MVC, you set up your route tables in `Global.asax.cs`:
public class FooApplication : MvcApplication { protected void Application_Start() { RegisterRoutes(RouteTable.Routes); } public static void RegisterRoutes(RouteTable routes) { // In ASP.NET, you have to define routes explicitly via routing table // definitons. These work similarly to how Backbone does things. routes.MapRoute( "Foos", "foos/{action}/{id}", new { controller = "Foo", action = "Index", id = UrlParameter.Optional } ); routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }
Or in Rails, your `routes.rb` file probably looks something like this:
FooApp::Application.routes.draw do # In Rails, however, you can define a `resource` via a model symbol name and # the framework just knows how to map RESTful URLs to it. resources :foos # You can also define individual URLs and map them manually. match '/about' => 'pages#about' root :to => 'pages#home' end
When we consider these two popular frameworks and how they treat their respective routing systems, we can draw the same conclusion about both of them. Routers are configuration. Yes, they're code files and not XML, Yaml, JSON or some other structured data file, but actual imperative code. However, any sane developer would never put any sort of business logic in these files, right? Right? **So if the established use pattern for routers in an MV* framework is to treat them as configuration files, then why treat Backbone Routers in any other way?** Not to sound all soap-boxy, but here's how I've been setting up my Routers in Backbone (with comments to hopefully help explain the important bits).
// Here's our Router "class" definition. There are a few things we need to wire up // before it's ready for action... var Router = Backbone.Router.extend({ // `initialize` is a standard part of every Backbone construct. It behaves // kind of like a constructor that accepts an object called `options`. initialize: function (options) { // Since I often use a presenter, I will instantiate it here and delegate // all application logic to it. Note that we're passing the options object // strait through to the Presenter. this.presenter = new Presenter(options); }, // This is our route table. In this JSON object, we can define any URL we // want to handle on the left side of the ':', and on the right side, we // list the name of the method that will handle that URL. routes: { '': 'index', // Empty string will represent "home" 'about': 'about', 'foos': 'listFoos', 'foos/:id': 'showFoo', // Note the 'id' URL param used here '*options': 'notFound' // `*options` is a catchall route in Backbone }, // Here's our handler for our home page. So if our website's address is // `http://foo.com`, a route with an empty string would catch the root // URL of the site. index: function () { this.presenter.showHomePage(); }, // Handler for the `http://foos.com/foos` URL listFoos: function () { this.presenter.showFooList(); }, // Here's the handler for `http://foos.com/foos/:id`. Notice that the URL parameter // `id` is mapped below as a function argument. showFoo: function (id) { this.presenter.showFoo(id); }, // The `*options` catchall route is a well known value in Backbone's Routing // internals that represents any route that's not listed before it. It should to // be defined last if desired. We'll just have the presenter render a 404-style // error view. notFound: function () { this.presenter.showPageNotFound(); } }); // To actually use our router, we'll just "new it up" and pass in any options necessary. // Let's pretend we already have a model populated with data that we're passing to it. var router = new Router({ model: foos }); // Now that we have a router object loaded in memory, we can start recording URL // history. Backbone.history worries about watching the URL and calling the appropriate // functions listed in the router's `routes` object. Here we're going to use HTML5 // PushState, so that we can generate cleaner looking URLs rather than hash-based ones. Backbone.history.start({ pushState: true });
Hopefully that helps demystify Backbone's routing system for those unfamiliar with how it works. When you really break it down to its most important bits, the Backbone.Router construct really is just fancy looking configuration. Think this'll help you write cleaner code? Let me know in the comments.
1 note · View note
jsondata · 12 years
Text
Aligning My Backbone
This is part 2 in my blog series on Backbone.js. Make sure to check out the [first post](http://jsondata.tumblr.com/post/25488008705) if you haven't read it already. In my last post I covered the basics on each part of Backbone and provided a very basic intro. Just to reiterate, Backbone.js is a MV* framework for writing complex single-page JavaScript apps. **It's just plain ol' JavaScript and is very un-opinionated.** These design choices make Backbone very flexible and incredibly powerful. My focus in this post will be why adding a bit of your own flavor, patterns and opinions can be highly productive. **Model View Presenter** While building lots of Backbone apps over the past 9 months or so, I've gotten cozy with the [MVP design pattern](http://en.wikipedia.org/wiki/Model–view–presenter). In MVP, the notion of a Controller is replaced by that of a Presenter. A Presenter behaves like a super-Controller. It not only concerns itself with acting as a proxy for the Model, it actually has some say over injecting the Views into the DOM and managing their lifecycle.  *But... But... But... Backbone doesn't have a Presenter!  How could you possibly use MVP in a Backbone app?* It took me a little while to wrap my head around this. So don't feel bad if you find yourself asking this very same question. I've asked it, and I'm sure many others have too. **You can create your own Presenter object. Not every piece of a Backbone app has to be a Backbone construct.** Let that sink in. Once you understand that you're just writing JavaScript, it's incredibly liberating. *OK fine. Enough talking. Show me some code!* At first glance you'll note that most of my code looks like the standard stuff you'll see in a Backbone app. The main differences will be seen in the Router and the Presenter itself. **Here's what the router would look like...**
    var FooRouter = Backbone.Router.extend({         routes: {             'foos': 'listFoos',             'foos/:id': 'getFoo'         },         initialize: function (options) {             // Pass options through to the Presenter             this.presenter = new FooPresenter(options);             _.bindAll(this);         },         listFoos: function () {             this.presenter.listFoos();         },         getFoo: function (id) {             this.presenter.getFoo(id);         }     });
No too shabby, eh? We're just passing everything through from the Router to the Presenter. Keeps the router nice and lean. It removes unnecessary logic and lets the Router focus on... um... routing! **And here's how the Presenter might look...**
    var FooPresenter = function (options) {         // Let's pretend that we've already got a list of Foos         // hydrated from the server.         this.foos = options.model;         _.bindAll(this);     };          FooPresenter.prototype.showView = function (view) {         if (this.currentView) {             // I often create a 'close' method off of Backbone.View             // to help Views clean up after themselves and to             // prevent memory leaks. I'll get into this in a future             // post on Views.             this.currentView.close();         }         this.currentView = view;         $('#some-container').html(this.currentView.render().$el);     };          FooPresenter.prototype.listFoos = function () {         var view = new FooListView({ model: this.foos });         this.showView(view);     };          FooPresenter.prototype.getFoo = function (id) {         var foo = this.foos.get(id),             view = new FooView({ model: foo });         this.showView(view);     };
That's pretty much all there is to it. If you're familiar with how "classy" objects get created in JavaScript and how the prototype chain works, you're in good shape. And just like with MVC Controllers, you want to keep your Presenter methods nice and lean as well. Nothing super complicated going on here. Remember, adding patterns you're already familiar with will help you become a better JS developer and will help you design little programs that you can compose into large, testable systems. In my next post, I'll cover how to manage messaging between the various components of your app to keep things nicely decoupled.
1 note · View note
jsondata · 12 years
Text
Hey, check out my Backbone
![Backbone.js](http://backbonejs.org/docs/images/backbone.png) This is the first post in what will become a series of posts covering [Backbone.js](http://backbonejs.org). I've been developing Backbone apps pretty heavily lately and have learned a lot. This series will serve to document what I've learned for personal purposes, and hopefully will be helpful for developers looking to learn more about it. **What's a Backbone.js?** Backbone.js is a JavaScript framework. Lots of people like to use it to build larger scale applications that run in a web browser, completely decoupled from their server framework of choice. It's an incredibly powerful tool to have at your disposal. There's so much information and buzz out there about this framework, though, that I think it may be best to start off describing what Backbone isn't. **Huh?** You'll often hear Backbone referred to as a client side MVC framework, like Rails or ASP.NET MVC. I disagree with this comparison. While its useful to provide context for what Backbone can do, it leads down a very confusing path where many incorrect assumptions get made. These bad assumptions often get made because of an unfortunate naming choice early on in the framework's development. In previous versions, the Backbone Router was actually called "Controller". Thankfully, right around the 0.5.3 release, Jeremy Ashkenas and team decided to rename "Controller" to  reflect its actual purpose: a Router. Confusing naming conventions aside, I like to call Backbone an MV* framework, where the * is basically a wild card (you could go with MVC, MVP or MVVM). Backbone has Models and Views. It does not, however, come with a baked in Controller (in its most current form). Because of the unfortunate naming mishap in earlier versions, many demos you'll run into out on the web will treat the Router as if it were a Controller. While this works from a technical standpoint, and is often the simplest implementation, I've found that it tends to lead toward a more limited understanding of the framework. I'll get into more detail on that later on in this series. I'm not going to go super in depth about each individual part of Backbone just yet, but here's the 10k foot overview: **Models** Like in most MV* implementations, in Backbone, models represent your data. They also have a lot of nice utility methods to handle data transport. You can tell a model where it lives on the server by passing it a RESTful URL root. And should you ever call 'save()' on that model, it will know how to persist itself. And, of course, you'll want to place much of your domain-specific business logic in these model objects. **Collections** Backbone collections are basically lists of models. The really nice thing about the way they're implemented. Thanks to Underscore, it's really easy to query, slice and dice your data on the client. [Underscore.js](http://underscorejs.org) is a dependency of Backbone and is super useful in its own right.  Underscore provides lots of nice utility functions that Backbone hooks into. Underscore is to plain ol' JS as [jQuery](http://jquery.com) is to the DOM. **Views** Views are the representation of your UI reflected as code. You get a lot of flexibility in how you choose to implement them, though. They can already exist on the page (rendered by the server), or you can populate templates (HTML fragments) with data from your models and have the view render them on the page. Views can listen for DOM events via jQuery or Zepto (whichever you happen to be using). This often makes Views feel a bit like Controllers in that they are often the entry point for user interaction in your app. **Routers** As I mentioned earlier, a lot of people make the mistake of thinking of the Backbone Router as a Controller, simply because it handles incoming URLs in a similar fashion that server-side MVC developers are often familiar with. In an upcoming post, I'll be diving into the pattern I use to avoid falling into this trap. **Events** Internally, Backbone uses an object based event binding system to enable a really elegant publish/subscribe implementation. You can use this feature to listen for events fired by models and collections. You can also extend this functionality to create your own event aggregator for your app, allowing different constructs or modules to talk to each other without unnecessary dependencies. **History** Backbone's implementation of browser history is where a lot of the magic happens. It watches the URL hash, or listens to PushState (if your app uses it, and the browser supports it), and will send the URL changes to your router to handle. This is really nice in that you can add bookmarkability into your single page JavaScript applications for free. **Wrapping up** Individually, these pieces aren't super special, but as a package, they become really powerful. It's also important to note that Backbone plays really nicely with other JS libraries, so it's very easy to mix and match things to create your own stack. In my next post, I'll be digging into the MVP (Model View Presenter) pattern that I use to build apps, and why adding a bit of your own opinions into Backbone can be really important and highly beneficial.
0 notes
jsondata · 12 years
Text
Musings on asynchronous programming in JavaScript
I had a brief discussion today with my buddy [Nick](http://twitter.com/airdo) and something he said struck me. And it may come across that I'm trying to pick on him in my post. But our little chat really got me thinking, as they often do (which makes Nick such an awesome guy to code with). So I thought I'd share...  I'll try to paraphrase Nick's statement as best I can. Here's the gist of what he said regarding writing large-scale, asynchronous applications in JavaScript (Backbone.js in this case): > *This technique of coding adds a completely different level of > complexity. It's not going to catch on until it gets easier for > developers to work with.* I agree with Nick's first thought. Asynchronous programming is a whole new ball game. It'll melt your brain in ways you never conceived your brain of ever being melted before. **... However ...** Async programming is still fairly new. It wasn't born yesterday, but it's new in the sense that it's just now getting it's time in the spotlight thanks to projects like Node.js, jQuery, and Backbone.js. It's new to a lot of us who have been stuck in the synchronous world for the past few decades. I disagree that async development (particularly using JavaScript in large scale applications) will have to get "easier" to be widely successful. I think it's going to require a different mindset of people who choose to work in that space. Asynchronous code is definitely not *"the path of least resistance"*. It's a different animal altogether. It's a complete paradigm shift, not unlike what the development community went though when hackers writing imperative code had to really sit down and grok Object Oriented Programming. I would also say that its probably not for everybody, and certainly not suitable for every project. I think for developers to be successful in writing asynchronous code, they need to stretch themselves a bit to wrap their minds around it and invest the time necessary to do it right. I'm sure there will be more and more libraries that come out that attempt to reduce the "callback hell" that comes with the territory, but the fundamental building blocks used will remain the same (closures via callbacks, promises, etc). It's awesome to see it maturing at such a staggering rate. This stuff makes it a fantastic time to be a developer.
4 notes · View notes
jsondata · 12 years
Text
Steve Jobs - by Walter Isaacson
I’m normally not one to write book reviews. If it's not directly related to design or code, I usually dont bother posting about it. I suppose I can make an exception just this once.
I just finished reading the biography on the life and career of Steve Jobs by Walter Isaacson. It was brilliant. All I can really say is “Wow”. I've got a newfound appreciation for who he was as a person, his genius and his accomplishments.
I saw a lot about his personality to disagree with, but I found that I resonated with his tastes and character far more than I expected, and I picked up a bunch of valuable takeaways from his experience. If you build or create anything in your career, whatever that may be, and you actually care about what you’re creating, you really ought to read this book.
0 notes
jsondata · 12 years
Text
More than just a house
This past Saturday night my wife, Rebecca, and I went to 1Mission's 2012 Gala and it was awesome. The guys that run that charity never cease to amaze me with the innovative things they do.  This weekend, I got my bell rung pretty good.
I'm no stranger to their cause. They build houses for the impoverished people living in the barrios of Puerto Penasco, Mexico. But I think that description of their mission is highly misleading and undermines what it is that they actually do. 1Mission is empowering these people to fix their own circumstances. 1Mission doesn't do traditional aid-type charity work. They partner with the locals by educating them, giving them a sense of ownership over their situation, thereby giving them a means to pull themselves out of it.
The video below is a great illustration of what they actually do...
1Mission has a unique take on the problem of poverty, and behind that perspective, they've created a very effective process. It's working wonders in their Penasco community. So much so, that other organizations around the globe are asking to partner with 1Mission so they can learn the process.
It's because of Jason Law, the founder of 1Mission, and his team's vision that I even began my work on Grassroots. It's an honor for me to be able to name some of these guys as friends and I consider myself to be super lucky to be involved, even in a small way, in what they're doing. I'm blessed to be able to partner with guys like this that "get it" when it comes to building Open Source Software that can have a profound impact on the people around them.
OK, enough mushy stuff. I'll leave you with one last video from the Gala this weekend. Hope you enjoy! Back to hacking!
7 notes · View notes
jsondata · 12 years
Text
Writing Node apps and bleeding everywhere
Well over two years ago, my wife and I renamed our side-business from Monkey Assassin Design Co to Jordan Rift. Along with the renaming, of course, we needed to rebrand everything. That meant new logo, new website, new business cards, etc.
Of course, I was a HUGE slacker when it came to all of these tasks. I've gone through 5 or 6 different iterations of the logo over the past two years. Many of them have been shot down by my better half (she was always right :). Some of those comps I've actually posted here previously. I'd often use this as an excuse for not having a website complete. For each iteration of the logo, I would convince myself that I had to completely redesign the website.
I actually had a few solid designs complete for the most part and nearly ready to go, but I never pulled the trigger. I'm really not sure why, but in hindsight I'm a little glad I didn't. Even though it cost us some additional time, I'm much happier with the final result than I have been with any of my other attempts.
If you've been hanging around me in the past few months, you know I'm a little nuts over JavaScript. So naturally, I wanted my business website to be an extension of that. I decided to write it in JavaScript, front to back. Here's my stack:
Node.JS on the server side
Express driving the HTTP functionality
Socket.IO driving much of the client/server interaction
Redis handling session management
All lovingly written in CoffeeScript
CSS written in Sylus
HTML written in Jade
Client-side code all written using Backbone
Hosted on my beta account via the great guys over at Nodejitsu
So without further ado, check out my latest creation. I'm pretty happy with the way it came out. And most importantly, Mrs Offutt is happy with it too.
Now this wouldn't be a very valuable post if I just displayed my site for everybody to gush over. I'm working to make an effort in my posts to present some value. Hopefully others can benefit from my fumbling around. So here goes nothing.
// Insert something helpful below...
I designed the new JordanRift.com as a single page app. It uses Backbone and HTML5 PushState to manage navigating between different views and updating the browser's history, while showing off some pretty scrolling transitions.
This presented an interesting challenge. PushState allows you to do client navigation without refreshing the page or resorting to hash-based navigation. The challenge this presents is that in order to make urls bookmarkable, you have to mirror routing on both the client and the server. Let's assume we have a Backbone routing structure that looks like this:
// Backbone code running on the client... var FooRouter = Backbone.Router.extend({ routes: { '': 'index', 'foo': 'foo', 'bar': 'bar' }, index: function() { // handle default route }, foo: function() { // handle foo route }, bar: function() { // handle bar route } }); $(function() { var router = new FooRouter(); Backbone.history.start({ pushState: true }); });
Because we're exposing 3 URL routes on the client, we'll need to have those reflected on the server. Because somebody could hit your page from an external link (e.g. - 'http://yoursite.com/foo'), routes on the server will be needed so a 404 doesn't get served up and leave your viewers staring at an error page.
// Node.js code running on the server... var express = require('express'), app = module.exports = express.createServer(); // ... configuration stuff... app.get('/', function(req, res) { req.render('index'); }); app.get('/foo', function(req, res) { req.render('index'); }); app.get('/bar', function(req, res) { req.render('index'); });
There may be a better way of doing that, but I just ended up creating separate route handlers in Express for each URL that would be exposed on via Backbone. Of course they're not quite that simple in production, but that's the gist of it.
Round 2: Fight!
The other interesting challenge came in implementing my socket server. Socket.IO needs access to a session store. By default it will use the "InMemory" session store. If you're using Connect (if you're using Express, you're already using Connect), you can actually have the two handshake and share session stores. This helps tie things together quite nicely.
The default InMemory store works great if you're only using a single Node instance. But if you ever plan on running your app in production, you'll need something more robust, because you're likely going to be hosted on more than one instance of Node. This is where Redis comes in. You'll often hear, if you work in the tech industry, that when you're using a new technology, there will be some bleeding involved. That proved very true in my first experience with Redis. I bled all over the place, but it was highly educational.
When browsing through the node-redis documentation, you will see examples that look like this:
var redis = require('redis'), client = redis.createClient(); client.get('somekey', function(err, data) { if (!err) { // do something with 'data' } });
What the documentation doesn't tell you is that when you provision a new Redis database through your hosting provider (assuming you're not using a dedicated server), is that while it creates the Redis instance for you, it just provides you a URL that looks something like this:
redis://nodejitsu:[email protected]:9117/
Now I may be many things, but I'm no *nix genius, so this looked pretty cryptic to me. Even the documentation was lacking a bit in this case. The node-redis createClient method takes a port and host argument, so my first guess was to try something like this:
var redis = require('redis'), client = redis.createClient(9117, 'redis://nodejitsu:[email protected]');
I was getting connection errors, and it required a bit of head scratching and research to figure out. This is actually what needs to happen:
var redis = require('redis'), client = redis.createClient(9117, 'cod.redistogo.com');
So that's great, but the connection errors were still happening. That was less apparent to me what needed to happen, but after more research, I figured out that the URL returned by Nodejitsu actually used a common pattern:
redis://nodejitsu:[email protected]:9117/ ^password ^host ^port
OK, so now I needed to figure out how to authenticate against my Redis database. Unfortunately the createClient method does not accept a 'password' parameter. It does, however, have an 'auth' method. Here's the final result:
var redis = require('redis'), client = redis.createClient(9117, 'cod.redistogo.com'); // Magical 'auth' method of auth-omeness client.auth('SOME-LONG-HASH');
So there we have it. My fancy new app was working with Redis. Socket.IO and Connect were handshaking and sharing my shiny new Redis session/cache store. Here's the resulting code:
var connect = require('connect'), express = require('express'), redis = require('redis'), RedisStore = require('node-redis')(express), client = redis.creatClient(9117, 'cod.redistogo.com'), app = module.exports = express.createServer(), parseCookie = require('connect').utils.parseCookie, sessionStore, port, io; redis.auth('SOME-PASSWORD-HASH'); sessionStore = new RedisStore(client); app.set('views', __dirname + '/views'); app.set('view engine', 'jade'); app.use(connect.cookieParser()); app.use(connect.bodyParser()); app.use(connect.session({ secret: 'keyboard cat', store: sessionStore })); app.use(express.static(__dirname + '/public')); app.get('/', function(req, res) { req.render('index'); }); app.get('/foo', function(req, res) { req.render('index'); }); app.get('/bar', function(req, res) { req.render('index'); }); port = process.env.port || 3000; app.listen(port, function() { console.log('App is listening on ' + port + '.'); }); io = require('socket.io').listen(app); // Here's the handshake magic between Socket.IO and Connect io.configure(function() { io.set('authorization', function(data, callback) { var sessionID; if (data.headers.cookie) { data.cookie = parseCookie(data.headers.cookie); sessionID = data.cookie['connect.sid']; sessionStore.get(sessionID, function(err, session) { if (err || !session) { callback(new Error('no session found')); } else { callback(null, true); } }); } else { callback(new Error('no cookie sent')); } }); }); // Now within Socket.IO transmission, I can fetch session information... io.sockets.on('connection', function(socket) { // Here's my session ID... var sessionID = socket.handshake.cookie['connect.sid']; // ... And you can do stuff with it... socket.on('foo', function(data) { var key = 'foo:' + sessionID; client.get(key, function(err, result) { if (!err) { // Do something spiffy with 'result' now... } }); }); });
It's not easiest transition in the world coming from an ASP.NET background where the runtime takes care of all this stuff for you, but being exposed to it and having a healthy understanding of what's involved can be very beneficial.
So that's what I've got for now. Hopefully, if you're in the same boat I was in, this will help you on your way. If you have any questions, or if I botched something, please let me know in the comments.
12 notes · View notes
jsondata · 12 years
Text
Going Dark
Not that there are tons of people that read my minuscule little corner of the Internet, but I'll be [going dark](http://americancensorship.org) tomorrow in support of the [protest against SOPA/PIPA](http://sopastrike.com). I'm fully aware that my tiny little blog, whose readership can probably be counted on one's fingers, really makes no difference. I will, however, be doing it as an act of solidarity. I figure if this legislation pisses me off enough to move all my domains away from GoDaddy, sign a White House petition, write numerous letters to my Congressman and Senators, and complain as loudly as I possibly can via social networks, I might as well black out my blog for 24 hours too. See you guys on the 19th!
0 notes
jsondata · 12 years
Text
Resolutions
Warning: Obligatory blog post reflecting on past 8,765 hours or possibly one musing on the upcoming 525,948 minutes ahead. Either way, proceed with caution.
This coming year one of the things I’d really like to focus on getting better at is keeping up with my blogging. Throughout the year, Nick and I get to work on some really cool stuff. Often times I let these little projects go by without really sharing anything about them. Which is kind of disappointing in a few ways, since often times, they end up becoming something others can benefit from.
So this year, I’m going to make a more concerted effort to post more often. I’ve even put together a new workflow to help me stay on top of it.
Simplifying… Sort of…
This past March, on my birthday, Steve Jobs thoughtfully decided to release the iPad 2. So naturally, I chose to spend part of my day waiting in line. Ever since, my shiny new iPad has become an important part of my work. Whatever things I can streamline enough to get done on the iPad I usually jump at the opportunity. Blogging seemed like a natural choice.
The challenge in this notion came from my choice in blogging platform. When I chose Tumblr for my blog, I chose it because it’s simple. In most respects this is true. However, it’s not the case when trying to blog on your iPad. The iPhone app that Tumblr released is really nice, but there’s nothing out there that’s really wonderful for the iPad yet, so I decided to take matters into my own hands.
Unsimplification
My primary blogging tool would of course have to be a text editor. There are loads of good ones out there on the app store. I ended up settling on Deadalus Touch. It’s got some really nice features, yet has a super clean, minimalistic interface. It also seems to handle markdown as a primary means of editing text very nicely. In fact, this is the first post I’m typing in Deadalus Touch. When I’m ready to post, I can export this all as markdown and paste it into Tumblr’s markdown editor.
To host images, I’m finally getting around to using Flickr. I just made myself set up my account to host images. Flickr, though, shares a fairly significant problem with Tumblr when it comes to working with it on the iPad. The iPhone app for Flickr is great, but there’s not  an iPad equivalent. No easy means to upload my blog images to Flickr. Which brings me to the last piece of the puzzle…
There’s this nifty new tool that’s been making it’s rounds on the interwebs called ifttt (if this then that). It’s nothing short of brilliant. ifttt is a central place for various Internet services you use every day. They hook into these service APIs and allow you to set up workflows. So for my blog, I set up a “task” that will use the Dropbox API and the Flickr API. If I upload an image to my public Dropbox folder, ifttt will upload that image to my Flickr photo stream. There are loads of other things you can do with this tool. It’s genius!
So that’s the gist of it. I’m hoping that by jumping through a few hoops right now to create this process will offer an end user interface that’s clean and minimal enough for me to blog anywhere on my iPad. So here’s to hoping that you’ll hear from me more regularly in 2012. See you guys next year.
0 notes
jsondata · 12 years
Text
Introducing CrowdSync
Crowd-what?
This year, Nick and I wrote a little CoffeeScript program along with some HTML, CSS and a bit of C# for good measure. If you visit a web page that this code is running on, it makes your phone blink a randomly assigned color at specific times throughout a song performance. Your phone becomes synchronized with many other phones blinking the same or different colors all in time with a musical track which is also being played by a live band. We call it CrowdSync.
The Challenge
In August this past summer, Kim Vehon (from Central's worship team) came into Nick's and my office. She showed us this video of cell phones blinking a single color and emitting a tone to create music. It was a pretty cool idea, but we weren't too sure where she really wanted to take it. I think initially, she wanted it as some part of the worship service element. Having phones somehow incorporated into the set that blinked with the music.
Initially, this sounded kind of boring to Nick and I. We thought, "What if we could make everybody's phone blink like this, rather than just a few phones on stage." An interactive worship experience sounded much cooler than a fancy set piece. So that's where this whole thing began. And it just snowballed from there, becoming bigger and cooler as we got closer and closer to Christmas.
Mr. Negativity
In the project's earliest stages I had convinced myself that there is no way that we're going to pull this thing off. Early on, I was Mr. Negative Nancy about the whole thing. The core problem we were trying to solve was what we geeks call non-trivial. That is to say, we had a mountain of a problem to climb: We needed to make everybody's phone blink at the same time. Not just roughly the same time. We needed them to blink at precisely the same time, with millisecond precision.
If you've never thought about this, here are just a few of the variables we found ourselves facing:
Inconsistencies in how time is kept on each device.
Time differences between carriers and even between devices on the same carrier.
Different operating systems and mobile browsers and the limitations they imposed.
Network latency between the phone and the server.
The complete lack of control afforded to mobile browsers by the client OS.
A great myriad of things that can happen whilst dealing with a phone (i.e. - What happens if somebody gets a phone call, or a text, or their phone goes to sleep?).
What's going to happen when a thousand people hit our web server all at once?
So you see, being the pragmatic geek that I am, I naturally thought there was no way we could pull this off. Boy was I wrong!
The Solution... Round 1
A couple days later, Nick went into a kind of fit of inspiration that would ultimately prove me wrong. I've been thankful for that every day since. :)
We initially talked about using something like Node.js with Socket.io to send push notifications to clients teling them when to "play". We decided fairly quickly that this approach would be too "chatty". We needed something that would be fairly quiet on the network to help solve some of our network scalability challenges.
Nick came up with the idea to start from a known time source, the server's time. We wrote a little C# web service with 2 methods. One method returns the current time, and the other returns a designated start time based on a campus ID passed to it. We would then interact with these services on the client via AJAX.
This solved the time inconsistency problem. But how do we deal with network latency? We ended up prototyping out a little bit of CoffeeScript that would poll the server several times asking for the current time. We then took the server's time and compared it to the client's time. We did this over and over trying to get the smallest variance between the client and server possible. Approximately 20 tries seemed to be the magic number of times to poll the server. This allowed us to kind of synchronize our watches with the server and get each of our clients doing things at the same time. Since the client time becomes relative to the server's time, in theory, this technique could even work across time zones.
OK, so we had the time problem down. Now we needed to know when to "play" our "note". So we set up a timer on the client that would check the current time against the known start time for our "song". We needed this to be very responsive, so we settled on doing this check 100 times a second. So like a little kid with a full bladder on a road trip, our little app asks "Are we there yet?" incessantly until it's time to play the note it's been assigned.
It took us about a full day to get a working prototype. And at the end of that day, we had something that would take an array of JavaScript object literals and play each note. We had all of our IT team's phones in our office all blinking in perfect unison. It was brilliant.
More Problems... More Solutions...
Now that we had a working prototype that solved our core set of challenges, we needed to address another core piece of the puzzle. How will we get the musical arrangement into a format our app could understand?
After some pestering, we were finally given a midi file exported from an mp3. It was the piano arrangement that would be played during the service, played one note at a time. Thankfully, Nick found a midi parser written in C# that was able to decode the midi file and convert it into an array of relative timestamps. So we could convert this timing metadata stored in the midi track into an array of JavaScript object literals. The server determined the start time of the performance, and each note had a time stamp associated with it that was relative to the start of the track.
We then took this data and converted it to our "adjusted" time on the phones. We could add this relative time to the start time of the song and then our phone clients would know when to play their note during the course of the performance.
Our next challenge was getting the light boards and band to fall in step with our blinking lights. Our lighting genius, David Empy, suggested we use QLab to fire the lights and the click track for the band. We ended up using QLab for the lights only and created a control panel that synced up the QLab Mac's time in much the same way that the phones became synced. This control panel allowed us to set start times for the performance at one of our campuses.
To synchronize the worship band with our app, we decided to fire the click track ourselves using WebKit's Audio API *. After working through a few performance issues, we settled on a method of pre-loading and running the audio in a way that would fire at exactly the right time. We then were able to use an offset to account for any lead-in time on the click track for the band. Not super straight forward, but it worked really well.
Creating the song visualization
This was probably the funnest part of the whole process for me. About a month and a half ago, Nick and I found out we were going to be responsible for creating a visualization to go on the side screens. This first started out as a grid of rectangles. Each rectangle represented a phone in the grid. This allowed us to create some pretty neat looking patterns, but it was ultimately limiting. Our worship team didn't think it was "Christmasy" enough (they were right).
So we went back to the drawing board and started playing around a little bit with the HTML 5 canvas element in conjunction with various pieces of audio API. We came up with programmatically drawing the Luminous graphic with code on the canvas and animating it with our CoffeeScript.
I enjoyed this part the most. Nick ended up coming up with the math that would plot each point of light on the tree (using some Geometry calculations that I don't think either of us have used since high school). We assigned the color randomly and filled it with a radial gradient.
We even worked on adding little subtle touches like fading the lights out rather than shutting them off abruptly, moving the center point of the radial gradient for each light around and adding a bit of flickering here and there to make the tree look more organic.
Gotchas
Initially, syncing with an NTP server (like time.apple.com or time.windows.com) sounded like a no-brainer. We learned fairly deep into the project, however, that is can throw a wrench in things pretty quickly. If all your clients are dependent on time, what happens if the server's time drifts?
Q: What happens when the server receives an NTP update and adjusts its time accordingly?
A: It starts serving up a new time to clients, that's different from original time. This is not good.
We also ran into this same problem on our QLab Mac that would fire the lights, and once again on our iMacs that ran the visualization on the side screens in the house and fired the click track for the musicians. Yep. Still not good.
It initially looked like "gremlins in the system", but we noticed that once we disabled NTP syncing and just had the clients keep time locally, our results became much more consistent. Since each client could adjust it's start time based on the delta calculated off the server's time, we could still maintain our synchronization between devices without relying on NTP.
Future iterations
Currently, all of our performance start times are accessed via an ASP.NET web service and stored as Lookups in our Arena ChMS database. We're going to be breaking this dependency in the next major release. We prototyped it out using Arena since it offered us many conveniences, but we'd like to make it more portable and not reliant on a proprietary ChMS product.
We've got plans to re-write the back end of the system using Node.js and Express to offer a RESTful API to access the relevant information based on campus. We'll likely be storing the data in a No-SQL database (MongoDB is looking pretty good) or perhaps something like MySQL if we end up needing a more traditional relational database engine.
I've got some other ideas that are perhaps a bit too abstract to go into here, but we're actually looking to make CrowdSync more of a real-time app. We've got some pretty exciting ideas that we're looking forward to exploring that should make the system better and more stable in future releases.
Conclusion (TL,DR)
Even though I was convinced we couldn't pull it off in the earliest days, we did it! We successfully synchronized many devices to blink colors at the exact same time. Not only did they blink their assigned color at exactly the right time in time with each other, we were able to make them do it in time with music being played by a live band.
It was a huge success and we are super blessed to be a part of such an awesome team that could pull something like this off.
Keep an eye on the GitHub repo we've set up. We'll be releasing the source code in the next few days. We're also working on a video to more easily demonstrate what the app is capable of doing. As soon as we've finished work on it, Nick and I will make sure it gets included in the README on GitHub (and on our blogs too).
Pop over to Nick's blog and give his post a read too. 
* I actually liked Mozilla's HTML 5 Audio API better, but Google's V8 JavaScript engine was just too fast for us to drop Chrome completely for this project. When you're 'ticking' every 10 milliseconds and painting a <canvas> or manipulating DOM elements, you really need to eek out all the performance you can get.
104 notes · View notes
jsondata · 12 years
Text
All your apps are belong to JavaScript
About 2 months ago, I had an epiphany. Web application architecture as we know it is currently going through a major paradigm shift. To some, this isn't a surprise, and if you've been hanging around me over the past several weeks, you've probably heard my crazed ramblings on this subject already. But I think it's true. Atwood's Law is dead on, and I think we're going to be seeing it proven over and over again in the next few years.
Maybe it's just me, or maybe when other developers get into hacking around with things like Node.js and Backbone.js, they start to understand the things that are possible with the most misunderstood little language on the internet the same way I did. Maybe when I combined this newfound understanding of possiblities with the joy of writing client-side code in CoffeeScript, something happened inside my head. Something definitely clicked...
I think a lot of it started after I read this post by Mystery Coder. If I recall, by time I read this, I had probably written my first Backbone/CoffeeScript prototype apps, and maybe done my first "Hello Node" tutorial. Mystery Coder definitely proposes an interesting future, and I think he's absolutely right. In my mind, the writing is on the wall. Too many things are falling into place to ignore it.
Browser wars over JavaScript performance only serves to benefit by increasing application performance and stability.
JS micro-farmeworks like Backbone, Knockout, SproutCore, are Cappuccino are becoming more common and more widely used.
CoffeeScript is gaining traction as the de-facto JavaScript "replacement" for writing client-heavy applications.
Node.js is quickly becoming more and more popular. (Did you know it's poised to overtake Rails as the most watched repo on Github?)
The rapid development trajectory of Node.js. (Especially when you consider the newly added native Windows support, IISNode and possible integration with Azure looming.)
Crockford's work on exposing the "Good Parts" of JavaScript is being widely accepted as the standard for writing JavaScript the right way. Turns out you can actually do real development in it.
Lets combine this with current trends in application design...
Web apps are needing to compete across more different mediums than ever before. 10 years ago, it was perfectly reasonable to have all your code on the server. But as user interface design standards progress and applications become more intuitive and beautiful (especially in the mobile space), web applications need to follow suit.
It's not OK to refresh the page any more. It's generally a bad idea to present your users with a cluttered layout. And you can't get away with your application's user interface becoming unresponsive for any period of time these days.
So what does all that mean? 
It means that single-page/real-time apps are going to become more and more pervasive. Heck, there's even a conference devoted to writing apps like this. Technologies like Node.js with Socket.io and SignalR are going to be responsible for tying the application logic that's going to be written primarily on the client to the server, enabling bi-directional communication.
The role of the server will be lessened. The back-end code you do write will stick to the things that the server is good at: authentication, data persistence, input validation, security checks and so on. While more and more application logic will be pushed out the client. It'll often be written in many CoffeeScript files, joined and compiled into a single .js file, then minified and obfuscated for inclusion on a web page.
One of the great things that will come out of this shift is the ability to share code and application state on both the client and server when you combine these various micro-frameworks to produce awesomeness.
It's going to be an epic time to be a developer.
Don't buy it? That's cool. Sometimes I think I'm crazy too. However, I'd encourage you give some of these pieces of information your attention.
Ryan Dahl intro to Node from JSConf.eu 2009
Ryan Dahl on the history of Node
Look at some of the examples of things that have been written using this approach.
Consider some of the influential companies that are getting behind this movement.
Let them marinate for a little bit. I'd also challenge you to dig into the JavaScript language and really learn it. Crockford's right. It does have some very elegant pieces, and when you learn to navigate around the bad parts, you can really write some pretty code with it.
What have you got to lose? Worst case, I'm still a lunatic, but you'll get better at JavaScript. And even if I am crazy, JavaScript is still the most important language on the web.
5 notes · View notes
jsondata · 13 years
Text
Making the switch
At the risk of sounding all "Hi, my name's Jason, and I'm a Mac", I decided to do a quick post about switching from a Windows-only development environment to a Mac environment, with a Windows 7 VM. It's been very beneficial, and there's been a lot to like about the new setup. Of course there's been a couple difficulties, but they've been fairly minor so far.
Why did I switch? Here was the thought process...
My old work laptop was in need of upgrade.
We collaborate with other churches who primarily Mac shops, and work very closely with our Communications team (another Mac shop). Sharing a common OS is probably a good thing.
Having the ability to test the software we write cross-platform is very nice.
Having cross-platform development tools and environments more readily available (easier access to things like Rails, CoffeeScript, Node, etc).
Virtualized MS development environment. Oddly enough, Windows 7 seems to run a little bit more stably in a Mac VM (can't remember the last time I had to restart my Windows VM).
Virtualized dev environment means easier backups.
Here's my new setup:
15" MacBook Pro w/ Lion (the 8-core i7 beast w/ 8g RAM)
Parallels Desktop w/ Windows 7 Ultimate from MSDN (dedicated 1/2 of my CPU and RAM to Windows).
Visual Studio 2010
SQL Server 2008
First, the bad:
Context switching between Mac and Windows OS is a little weird. I probably need to play with my key mappings in Parallels, but having to switch between the cmd key and ctrl key depending on which app I'm using gets a little tedious.
Followed by, the good:
Within the native Mac OS, I've been really liking TextMate. I've actually been using it as my primary development tool for any JavaScript/CoffeeScript stuff I've had to write (even though R#6 has some really nice JS intellisense in VS now). I like the light weight feel, the simplicity and the extensibility of it.
Learning the Unix shell has been a bit of an uphill battle, but it definitely has its benefits. It's nice to have easy access to the CoffeeScript compiler now that it's in my $PATH. I can cd into my Windows environment and compile all my CoffeeScript as I write it. This was a little more clunky with the limited support in Windows for CoffeeScript, I know it'll get better in the future, but for now, I'm really liking this workflow.
Having all the latest tools at my fingertips has also been a huge plus. I have ready access to Ruby, Rails, CoffeeScript, Node.js, Python, etc. Since I've been playing around with Rails and doing LOTS of CoffeeScript lately, this has been one of the biggest plusses for the geek in me.
35 notes · View notes
jsondata · 13 years
Text
The Rails Way...
I've got a little confession to make. I've always been a little jealous of those Ruby on Rails guys with their fancy Macbook Pros, their super trendy web framework, and the awesomely weird names they have for things (like Cucumber, Webrat, Heroku, Spork, etc). I've had this sense of awe at how they managed to survive without some super high-powered IDE like Visual Studio. I'd say things like, "Just a text editor and a command line is all they need? Poppycock!".
I've always been a little freaked out by the command line. I know that makes no sense. I'm a software developer. I type thousands of lines of complex instructions into a large window. Why can't I type a few single-line instructions into a little black console window? Weird, right?
I decided to do something about that. I've been looking for a good secondary web framework to develop in for a while now. PHP has become so ubiquitous on the web, that it seemed a little silly not to learn it, but there's also that little nagging part of my soul that hates PHP with the heat of a thousand suns.
Rails, however, seemed like a great fit. I'd get over some of my weaknesses with the command line, and then I could talk like those weirdly awesome Rails guys that are always hanging around the Gangplank.
I picked up this book over the weekend and haven't wanted to put it down since. Rails is great so far. There's a lot to like about the Rails stack (apparently Microsoft thought so too). I'm an MVC guy at heart. I think that architecture fits web apps like a glove. Ruby is a great language. I don't feel dirty programming in it or fear that my entire app could explode in a great ball of fire and poor encapsulation. It's getting me into using the command line more and exposing me to new ideas and techniques.
So now I have this shiny new toy called Ruby on Rails. It's super cool and trendy and all the popular kids like Ruby on Rails. But my favorite toy is still ASP.NET (MVC flavored). I think they'll make a pretty good combo...
17 notes · View notes