Chainable methods…

So I’ve set about building a library of sorts…it may amount to nothing, but it’s turning into a seriously useful learning experience for me if nothing else.

Anyhoo, I wanted to be able to chain various methods together, à la jQuery or d3, code that looks like: something().dothis().makeoneofthese().change()… ad infinitum (feel free to steal those method names by the way…)

So here’s what I was hoping for…(es6-y code to follow):

*** Thing.js ***
// define a class
export default class Thing {
   example() {
      console.log('example method')
   }

   chainable() {
      console.log('I called another method!')
   }
}

*** thingFunc.js ***
import Thing from './Thing';
export default function thing() {
   return new Thing()
}

*** main.js ***
// this file included in index.html
import thingFunc from './thingFunc';

thingFunc().example().chainable();

The problem with this code is that it’s entirely meaningless and trivial…but the relevant problem is that it returns an error, specifically something like: “e… .chainable() is not a function”; which confused me at first, because it is. But here’s the thing to consider: what are you calling the methods on?

Calling thingFunc() returns a Thing, so .example() is called on that Thing…but .example() gives us nothing back; and nothing.anything() isn’t going to work. The solution, therefore, is a simple one…all your class methods must ‘return this’; so all subsequent methods have something to call on… here’s the modified code and not an error in sight:

*** Thing.js ***
// define a class
export default class Thing {
   example() {
      console.log('example method');
      return this;
   }

   chainable() {
      console.log('I called another method!');
      return this;
   }
}

*** thingFunc.js ***
import Thing from './Thing';
export default function thing() {
   return new Thing()
}

*** main.js ***
// this file included in index.html
import thingFunc from './thingFunc';

thingFunc().example().chainable();

Chain away my friends

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s