Backbone.js Patterns Pt.2: Don’t make me think
Different programming languages have different naming conventions. When working with Ruby, for example, it is advised that you separate multi-word variables with underscores. In JavaScript, camelCasing is generally the norm. So when dealing with data that is shared across different environments, you may find yourself having to remember what style to use, e.g. “Was it user.get('first_name')
, or user.get('firstName')
?”.
This is where humps is your friend.
humps is a small JavaScript library (~100 LoC) that simply converts underscored object keys (and strings) to camelCased, and vice versa (as well as other styles, like PascalCase). By using humps in the toJSON
and parse
methods, we can seamlessly work with the conventions of each language.
toJSON
and parse
are methods that are typically used to customise the data being sent to and from the server. toJSON
should be used to prepare a model’s attributes for synchronisation [1]; whereas parse
is typically called when data is sent from the server, and therefore can be used to prepare a model’s attributes before they are set on the model itself.
Starting with the parse
method, overwrite Backbone.Model.prototype.parse
, passing the results of the old `parse` method into humps.camelizeKeys
:
(function() {
var oldParse = Backbone.Model.prototype.parse;
Backbone.Model.prototype.parse = function() {
var parsed = oldParse.apply(this, arguments);
return humps.camelizeKeys(parsed);
};
})();
So now, the following JSON:
{ "first_name": "Jon", "last_name": "Snow", "is_steward": true }
will be converted to camelCase and will be accessible on the model as follows:
// assuming user is an instance of a Backbone model
user.get('firstName'); // "Jon"
user.get('lastName'); // "Snow"
user.get('isSteward'); // true
Remember, that parse
is only called when a model’s is updated via a fetch
or save
. If you are populating a model’s attributes manually, you’ll need to pass in { parse: true }
:
var user = new User({
"first_name": "Jon"
}, { parse: true });
It’ll also work with nested objects.
The same pattern can be applied to toJSON
, which will convert camelCased object keys (back) to underscored:
(function() {
var oldToJSON = Backbone.Model.prototype.toJSON;
Backbone.Model.prototype.toJSON = function() {
var json = oldToJSON.apply(this, arguments);
return humps.decamelizeKeys(json);
};
})();
Feedback welcome via Twitter, or email.
Part 3 in this miniseries will extend the toJSON
method to exclude non-persisted attributes from its output.
[1] The Backbone.js documentation for toJSON
previously suggested that it could be used to clone a model’s attributes for use in a template, as well as for persistence. Following a discussion on the purpose of toJSON
, it was decided that this “double duty” should be simplified. It is now not recommended for preparing a model for rendering.