Backbone.Model: Selective Saving

One of the most frustrating things I ran across when I first started using Backbone.js was the way in which models updates were sent to the server. The documentation includes the following:

“The attributes hash (as in set) should contain the attributes you’d like to change — keys that aren’t mentioned won’t be altered — but, a complete representation of the resource will be sent to the server.”

When I read that, my heart sank because POST or PUT operations to our API only allowed certain fields to be passed as many attributes were immutable. I discovered that I wasn’t alone in this particular quandary as a search on doing selective updates with Backbone.js revealed many people wanting to know how to do the same thing.

I tried several things, but most had to do with changing the Backbone.js source code; something that I really didn’t want to do. But taking a deep-dive into Backbone’s source, I discovered a couple of interesting blocks of code in the Backbone.sync object, that ignited an idea. The first block was simply this:

if (!options.data && model && (method == 'create' || method == 'update')) {
  params.contentType = 'application/json';
  params.data = JSON.stringify(model.toJSON());
}

Basically the conditional checks for the existence of options.data. If it existed, the code within the conditional would not execute; meaning that the model would not be copied to params.data. Then I got really excited when I saw the last line of code in Backbone.sync:

    return $.ajax(_.extend(params, options));

In that line, options is mixed into params! That meant that I could define my options.data outside of Backbone.sync and pass in only the fields that I wanted to post!

I won’t go into all the niggling details behind coming up with a solution, but suffice it to say that I found that the best thing to do was to make a descendant model of Backbone.Model and override the save method. The following override method will allow you to save only the fields you want to save. It will also handle the case where you do a model.set({fields}) then just all a raw model.save(), as the parent save is invoked via a call at the end of the method. Here’s the override:

    save : function(key, value, options) {

        var attributes={}, opts={};

        //Need to use the same conditional that Backbone is using
        //in its default save so that attributes and options
        //are properly passed on to the prototype
        if (_.isObject(key) || key == null) {
            attributes = key;
            opts = value;
        } else {
            attributes = {};
            attributes[key] = value;
            opts = options;
        }

        //Since backbone will post all the fields at once, we
        //need a way to post only the fields we want. So we can do this
        //by passing in a JSON in the "key" position of the args. This will
        //be assigned to opts.data. Backbone.sync will evaluate options.data
        //and if it exists will use it instead of the entire JSON.
        if (opts && attributes) {
            opts.data = JSON.stringify(attributes);
            opts.contentType = "application/json";
        }

        //Finally, make a call to the default save now that we've
        //got all the details worked out.
        return Backbone.Model.prototype.save.call(this, attributes, opts);
    }

The beauty of this is that it doesn’t require the alteration of any of the Backbone.js source code.

Advertisement

On Classical Inheritance in JavaScript

Whenever I get involved in conversations revolving around classical inheritance in JavaScript, I usually have a couple of comments:

  1. Geez! Man up and learn the f-in’ language!
  2. JavaScript is a class-less language, why would you want to do classical inheritance?!

Comment 2 is usually followed by a variant of Comment 1.

Earlier this year, I wrote a short quip on not buying into Parasitic Inheritance trend. Prior to landing my current gig, I had interviewed with several companies that were employing it in their applications. The things they were doing were very cool, but the reason almost all stated for using it was that they didn’t have to use “new.” I brought up the issue that in order to create a descendant, you had to make an entire copy of the ancestor, then tack on the new methods; whereas natively, it was a simple graft of new methods onto the ancestor. It fell on deaf ears as they justified what they were doing by citing Crockford’s work on classical inheritance in JavaScript.

But I don’t think they read the very end of the article in which he states – in a bordered box no less – that his attempts to support classical inheritance in JavaScript was a mistake. Here’s the text:

I have been writing JavaScript for 8 years now, and I have never once found need to use an uber function. The super idea is fairly important in the classical pattern, but it appears to be unnecessary in the prototypal and functional patterns. I now see my early attempts to support the classical model in JavaScript as a mistake.

The challenge with JavaScript is that it is a wide open language; you can do just about anything with it. But just because you can do something doesn’t mean that you should…

Yeah, I’ve heard all the complaints over the years – coming especially from former Java programmers. But I just keep on going back to the two comments I made above, especially the first comment. My belief is that if you’re programming in a particular language, learn the f-in’ language. Don’t try to place a different model or pattern on the language just because you’re used to programming in another language. To me, doing that is the ultimate in bullshit hubris. JavaScript is a powerful language, though admittedly it does have its shortcomings, but if you take the time to learn the mechanics of the language, there’s not much you can’t do with it.

Don’t Be Afraid to Scrap Your Code

I once got this “emergency” project where I had three weeks to deliver a mobile prototype application that was to be demonstrated at a major user conference. I spent the first week creating a UML design for the app – also looking for a back-end guy to build the Java API’s for me to call. Then spent a few days prototyping some assumptions and testing our JavaScript library’s capabilities on various phone-based browsers. Once I proved that out, I had roughly 7 business days – plus a weekend – to deliver the project.

Five days and almost 600 lines of code into implementation, I realized that I was doing a boatload of coding; way too much, writing lots of code that to address things that I hadn’t considered in my design. So I stopped coding, opened up my design, ran through the sequence diagrams and realized that what would’ve helped was having an intermediary object act as a ViewController and manage the various view objects. So went back to my class diagram, inserted the new object with the methods and properties that I expected it to have, re-worked my sequence diagrams then went back to my main JavaScript file and…

…completely erased it…

I mean, Select All -> Delete.

When I redid the code, I finished it with less than 50% of the original lines of code and actually checked it in with a day to spare. During testing, only cosmetic flaws were found, but no functional errors. I fixed those flaws and the prototype was released and demoed live at the conference in front of over 1000 people. The point to all this is that once I had the right design, the coding was absolutely simple and straight-forward. I wasn’t writing any compensatory code or dealing with deficiencies in my design because the design was right.

Moreover, erasing all my original work ensured that I wasn’t influenced by my old code. I had to start with a clean slate. But in the end, I still beat my deadline by a day.

Now, this isn’t something I recommend for huge projects, but as a rule of thumb, if you find that you’re writing a lot of code – especially with object-oriented JavaScript – chances are your design is flawed. At that point, stop, re-evaluate your design, and back up to a place in your code where you can adapt to the better design. Yes, sometimes that means getting rid of all of it, but most of the time, you can back up to a reasonable place without erasing all your code. But in either case, don’t be afraid to scrap code; especially if it means that the final product will be superior to what you originally created.

Want Your Team to Write Maintainable JavaScript? Start Making Them Think Alike…

A colleague at work today posted a couple of JavaScript/Front-End Development conferences that are coming up in the near future. One of them, the O’Reilly conference has a speaker talking about writing maintainable JavaScript. I did a bit of searching on him speaking about this topic, and the material that he presents is generally pretty good – at least from a coding standpoint. But I think that focusing only on coding won’t solve the problem. From personal experience, nothing can mess up maintainable code more than bad or non-existent design practices.

I know I don’t get too much traffic to this blog, but for those who have read my technology articles, they’ll know that I have a real design focus. Why? Simply because high-quality, easily maintainable software starts with good design, and I have LOTS of personal experience in this. I was able to get roughly 200 front-end engineers at a previous company to code the same way – in a maintainable fashion – by first teaching them good design practices. It all started out with using UML as the way to communicate our designs, then writing good technical design documents to describe and discuss the diagrams, then writing code that followed the designs. Of course, included in the process were both design and code reviews ensuring that the final product that was produced with lots of input and feedback.

Most would think that adding all this onto the development process would tack on more time to development. Admittedly, at first it does. That’s the “learning tax.” But once people are used to doing designs, and going through a few review processes to defend their designs and code, they become faster at development; much faster than they were before they started practicing “design first, code later.” While this also requires an overall organizational acceptance, it’s an easy sell because the overall code quality will shoot through the roof.

Plus, doing design then coding is the fundamental difference between software engineers and code monkeys. I’ve been around long enough in this industry to say that most software developers, though they like to think of themselves as engineers are code monkeys; albeit, with varying levels of experience. The more experienced developers will most likely be able to tackle a problem and get it right a lot of the time, but to me, when there’s not a design to accompany the development, there’s always a risk that problems that could’ve been mitigated and avoided with a design will trickle through. That’s not to say that a design will mitigate all bugs. That’s ridiculous. But you can avoid lots of problems simply by doing a design and following it; that is, implementing code according to what’s described in the design.

To crystallize the point further, let me say this: Code is PRODUCT; design is engineering. And when people are designing in the same way, they will tend to adopt coding practices and standards that are similar and maintainable throughout the organization.

So which do you want to be, engineer or code monkey? If you’re not already doing design, you know who you are…

A Real Pet-Peeve

Now that I’ve pontificated on the virtues of design, I’ll discuss code. The speaker on writing maintainable JavaScript, Nicholas Zakas, is quite an engineer, currently a principal at Yahoo. But in reading through his blog and reading through the conference highlights, plus reading this article that he wrote on the subject, he missed a VERY important point that is one of the very things that pisses me of more than anything else and that is lack of comments. I’m very good about commenting my code simply because once I’ve got it checked in, I want to be able to get a gist of the flow when I return to it weeks, months, or years from when I wrote it. I also do it so that others who may maintain my code after I’ve left know what I’m doing in my code.

I’ll just say it plainly: Commenting code is Programming I; not 101. You should be commenting your code from the get-go. Period. It’s such a key component to team coding and writing maintainable code, but it is often missed in talks and lectures because it’s assumed people do it. Nick, believe me, they don’t. 🙂

A Particular Caveat About Backbone.js Development

I’ve been developing an MVC application using Backbone.js as my MVC engine. This is a very powerful framework and its capabilities extend beyond a proprietary MVC engine that I helped develop in a previous company. One thing that I absolutely love about Backbone.js is how you can use a third party DOM library such as jQuery. With the proprietary MVC engine I helped develop, we actually stringified our HTML and wrote it all out with innerHTML, and DOM operations were performed with DOM scripting. You might think this is screwy, but it ensured that we followed a fundamental rule: No component could know about another component’s DOM. The net result is that all view objects were completely encapsulated and their DOM’s protected from other objects.

With jQuery and other DOM-scripting libraries, all you need is a selector, and that sort of opens up your views’ DOM’s to be open to manipulation. I even found myself starting to do this in a module that I built where a two-column informational table was actually constructed from four different data sources and four different views. Luckily, I fell back on my old experience and made the conscious decision that my individual views would only know about the specific section of HTML for which they were responsible. But I could’ve easily broken the rule that a component only knows about its DOM and its DOM only.

You might ask, “So what? What’s the harm in that?” There’s actually not much harm of that, but if you have two components competing for the same patch of HTML, you could have some deleterious results. So my advice here is relegate your views to specific sections of HTML on they and only they act upon. This will ensure that you won’t stepping all over yourself and having to deal with resource contention.

If You Adopt a Pattern, Stick with the Damn Pattern!

This is a bit of rant, but something that I’ve seen time and again in development groups that I’ve worked with over the years: Engineers adopting a design pattern then falling out of the pattern when it’s convenient. The most egregious is breaking out of the MVC pattern when the interaction gets difficult. Don’t get me wrong, there will always be exceptions; but especially in UI engineering, I see a lot of “falling back” on the tried and true DOM-based operations before adequately exploring whether or not it can be done within the context of the particular MVC engine that is being used.

There are several reasons for breaking from the pattern:

  • JavaScript is wide open, and there are lots of ways to skin a cat, so if you hit a bit of a roadblock, there are lots of tools available to solve the problem. But in rebuttal to that, just because you can do something, should you?
  • Because JavaScript is not strongly typed, enforcing patterns is difficult at best. Everyone has to buy into it.

What I see a lot of is falling back on DOM-based libraries such as jQuery. For instance, if you want to show a popup window to display some information from the server when a user clicks a link, the MVC way would be that the view that holds the link intercepts the click, triggers an “action” event of some sort which is intercepted by a controller that would then tell a DAO that would retrieve the information from the server. When the data is available, the DAO would fire a “data available” event that a model is listening to; the model in turn would update itself, trigger a “change” event to which a view is listening. The view updates itself, then displays the results.

This seems a little convoluted and complex but what it ensures is that you have proper separation of concerns; each different component is responsible for only what it was intended to do. The anti-pattern to this is just call a function and use jQuery or another DOM-based library to handle it all, which is totally easy. You make the call, use jQuery’s AJAX method, then display the message with a jQuery modal dialog. Simple.

But here’s the problem with that: Once you go that route, you’re using an external entity outside of your MVC system that acts completely independently of your system. That entity combines MVC and DAO operations. You could argue that that makes it a self-contained MVC. But that would be wrong because there is no separation of concerns, which is what MVC is all about. If you’re going to follow the pattern, there are no multi-roled objects.

Furthermore, the approach that is commonly taken is to make that function globally available because “Hey! It’s a cool function that we could use everywhere!,” which usually means polluting the global namespace. That has some serious security implications when you do that because you’re exposing the function to the world, and because that function is making an open server call, it is possible to expose it to CSRF attacks. Not good.

You see this behavior mostly from developers who are new to MVC. So how do you teach them? Simple. You have to get team buy-in to specific rules:

1. Obey the knowledge barrier. Look at the diagram below:

The solid lines represent direct knowledge from one entity to another. From that we can see that the controller knows about both the view and the model, and the view also has direct knowledge of the model. The dashed lines represent an implicit knowledge in that the only way for those entities to communicate with the destination object is via messages/events.

2. I mentioned this above: No multi-role objects.

3. DOM-based libraries should only be used to interact with the DOM; that is, they’re mostly used as helpers for the views. However, since they also have AJAX capabilities, they can also be consumed for use with DAO operations, but a DAO object should always be relegated to that whether the DAO is explicitly or implicitly declared. For instance, Backbone.js utilizes jQuery’s AJAX for CRUD operations. In that case, the DAO is implicit, and actually obfuscated from the developer as the models and collections interact with the Backbone.sync object which is itself a DAO.

4. Finally, to mitigate shortcuts, developers have to learn and practice good architecture and design; that is, they need to start using some sort of class and object interaction description methodology such as UML.

Those are four simple rules. Having taught this over several years, I know how difficult it can be to enforce and have developers obey them because the temptation is to always go the easy route. But great programs can only be created with a thoughtful approach to building them. Just as in construction, you wouldn’t build a house without a blueprint, and when you’re building you wouldn’t use construction methods that don’t follow the standards. Why would you do this in software?

Wednesday JavaScript Meanderings

On JavaScript Parasitic Inheritance

Hmmm…. Not sure that I really buy into all the craze in Parasitic Inheritance the last couple of years. Perhaps I’d buy into it if I heard a really great technical explanation, but thus far, all I’ve heard and read about the virtues of Parasitic Inheritance center around not having to use “this” and “new.” My reaction to that line of reasoning is “So what?” “this” and “new” are artifacts of the JavaScript language. Deal with it. Another line of reasoning used to justify the use of Parasitic Inheritance is the concept of the durable object, which is defined as “A durable object contains no visible data members, and its methods use neither this nor that. Again we return to the non-use of “this.” And again, “So what?” You can achieve something similar this using while defining a custom object in the traditional way:

function myObj() {}

myObj.prototype = (function() {
    function myPrivFunction(myArg) {
       return ...do something with myArg...
    }
    return {
        myMethod : function(param) {
            return myPrivFunction(param);
        }
    };
})();

You can have a whole set of private functions defined above the return that will not be changeable to the outside world. Furthermore, one of my biggest problems with Parasitic Inheritance is that you lose instanceof. Yes, there are ways to deal with it, but most of the examples I’ve seen deal with overriding Object and Function prototypes, or creating some intermediary “helper” function to enable instanceof with Parasitic Inheritance. My thought about this is if you have to make changes to the core of the language, then the “solution” you’re providing is simply an interesting engineering exercise.

On MVC: Put the DOM in Its Place, Dammit!

One of the things I see quite a bit of when working with JavaScript developers who are relatively new to using MVC frameworks such as Backbone.js is that their thinking is very DOM-focused. And while MVC in JavaScript does mean interaction with the DOM through the View, most developers focus their thinking around the View. As a result, their programming is all about direct references. But MVC is about separation of concerns, and each part of the MVC has an important role to play. As such, one of things that I do my best to help “teach” is having developers divorce themselves from DOM-based thinking, and start thinking at a much higher level; specifically, the system or application; breaking the application or system into constituent MVC parts.

Admittedly, it’s difficult for many to make the conceptual leap into MVC thinking because what we as UI Engineers produce ultimately shows up on the DOM. But the DOM is a by-product of MVC interaction. Once you get that concept down, then thinking with a perspective of MVC becomes quite easy.

It doesn’t help matters much when you have examples that are very DOM-focused, as many developers that move over to MVC are expert in jQuery or YUI or prototype.js, what have you. As a result, these developers provide examples that lean heavily on that previous experience. It’s a bit of vicious cycle.