Quick Links

Other stuff

Site owners

  • Bruce Mcpherson

Chaining JavaScript

One of my favorite JavaScript things is the ability to chain things together. 

Consider this function, where the methods return the instance itself;

var myBox = function () {
    var self = this, _height, _width;
    
    self.setHeight = function (height) {
        _height = height;
        return self;
    };

    self.setWidth = function (width) {
        _width = width;
        return self;
    };
    
    self.getSize = function () {
        return _width * _height;
    };

    return self;
}

We can call it, chaining together multiple actions.

  Logger.log ( 
    new myBox()
        .setHeight(20)
        .setWidth(30)
    .getSize());


In my opinion (some would disagree), this is more readable than

    var b = new myBox();
    b.setHeight(20);
    b.setWidth(30);
    Logger.log(b.getSize());

When I create these kind of functions, I always like to make them chainable, so when you use any of my libraries, and you like chaining, look out for opportunities to do this. 

On the other hand, too much chaining can lead to unreadable code (remember that others may have to read it too), and a lack of proper error handling. That said, chaining can give a remarkably concise way of expressing a complex set of actions - and I just like the way it all fits together. 

In this example below,  all in one chained statement, using the best foreign film academy awards nominees over the years, here's how to get data from a fusion table, use crossfilter to summarize and sort it, and output the result. I'm Using crossfilter with Google Apps Script along with Database abstraction with google apps script. Here's a snip of the input fusion table.


and here's the code

  Logger.log(JSON.stringify(
    cCrossFilter.crossfilter(
      new cDataHandler.DataHandler(
        '1d9ZLEcB7dnptI2VFaUqTuaIiLvlkmZBzCbwlaeG2',
        cDataHandler.dhConstants.DB.FUSION,
        undefined,
        'ie')
      .query().data)
      .dimension(function (d) { return  d["Submitting country"]  ; })
      .group()
      .top(Infinity)
      .map(function(p,i) { 
        return {times:p.value, country:p.key};
        })
  ));

which gives me this output
and a snippet of the result
[
{
"times": 38,
"country": "France"
},
{
"times": 30,
"country": "Italy"
},
{
"times": 19,
"country": "Spain"
},
{
"times": 15,
"country": "Japan"
}, etc...

Taking that just a little further (and why not), we can do all that and write the processed results directly to a spreadsheet (again using  Database abstraction with google apps script) all at once.

  new cDataHandler.DataHandler(
  "cross",cDataHandler.dhConstants.DB.SHEET,
  undefined,
  "12pTwh5Wzg0W4ZnGBiUI3yZY8QFoNI8NNx_oCPynjGYY")
  .save(
      cCrossFilter.crossfilter(
        new cDataHandler.DataHandler(
          '1d9ZLEcB7dnptI2VFaUqTuaIiLvlkmZBzCbwlaeG2',
          cDataHandler.dhConstants.DB.FUSION,
          undefined,
          'ie')
        .query().data)
        .dimension(function (d) { return  d["Submitting country"]  ; })
        .group()
        .top(Infinity)
        .map(function(p,i) { 
          return {times:p.value, country:p.key};
          })
  );

and here's a snip of the final spreadsheet.


Not for everybody of course, but taking a fusion table, summarizing it, sorting it and writing the result to a spreadsheet in (kindof) 1 line of code is pretty nice.


For help and more information join our forum,follow the blog or follow me on twitter .

Comments