Flux Stores and ES6

strange bed fellows


I’ve recently really been enjoying 2 things (amongst others!):

  • the Flux approach to building JavaScript front-ends
  • learning and starting to use ES6

Flux

With the seemingly endless proliferation of JavaScript MVC code libraries, it is refreshing to find a “framework” that is less code and more concept. Indeed the Flux library which Facebook have released as part of their open source initiative is just a few lines of code.

Even more compelling for an aging rhebel like me, is that Facebook have had the boldness and wisdom to think beyond the panacea of MVC and come up with their own approach based around uni-directional data flow. It may sound like heresy but I am finding that it works incredibly well when combined with Facebook’s React and helps to build well-structured and maintainable web applications.

ES6

The “new” version of JavaScript — ECMAScript 6 — seems to have been on the horizon for a very long time but finally it is approaching ratification. As I am determined to move back into programming after a lengthy IT career spent mainly in PowerPoint, I’ve decided to focus on ES6 as my playground and thanks to the excellent Babel it is of course possible to “transpile” ES6 code back into earlier versions of JavaScript so that the code can run in current browsers.

So my current passion is writing Flux/React applications in ES6. Which bring me on to the strange bed fellows…


Flux Stores in ES5

The diagram below is Facebook’s diagram to show the basic Flux uni-directional data flow. Stores are where the application data and logic are held.

There should be one Store in the application to represent each logical domain e.g. OrderStore, ItemStore etc. And in Flux, each Store is implemented as a singleton. The gist below shows the standard skeleton for a Flux store implementaton in ES5.

Line 9 is where the singleton is declared by assigning the properties of EventEmitter and our own code to an empty object instance {}. This merged instance is then exported as the singleton.

Many develeopers using Flux in ES5 (including me!) often put the boilerplate Store code into a separate file and then define the actual Stores based on it. You can see a very good example at this link where Store.js defines the boilerplate and AppStore.js is the actual store being used for the application logic etc. The declaration of Store and AppStore are the interesting parts for the purposes of this story:

function Store() {}
assign(Store.prototype, EventEmitter.prototype, {boilerplate...});
var AppStore = assign(new Store(), {specific...});

Merging the properties of EventEmitter is now taken care of in Store.js, and then the author, zertosh, merges a new instance of Store with the AppStore specific properties. Again what is exported therefore is an instance of a singleton object rather than just the definition of an object.

Flux Stores in ES6

And so finally we get to ES6. What’s the big deal I can hear you saying if you have managed to get this far. All you need to do is to port the above example to the ES6 syntax — job done and zertosh has done all the real work! Well, I didn’t find it quite that easy.

At first it all seems like a match made in heaven. Instead of the somewhat clumsy assign statement and the always confusing .prototype property we can now use ES6 classed to “inherit” from EventEmitter. So in ES6, Store.js now becomes incredibly elegant (by my standards anyway!):

And then onwards to AppStore.js — we can now just extend from Store.js and we have more elegance. Unfortunately not. As we have seen, the zertosh code “inherits” from an instance of Store by merging with new Store() — how to do that in the new and improved world of ES6? At this point I started to struggle.

Whatever I tried, the class statement in ES6 appears to always return the declaration of an object, not an instance of it. I suppose that is what it is designed to do! So I searched the web for the subject on everyone’s mind “how to declare a singleton in ES6”. Many of the search results indicated that singletons are evil and must be avoided. That wasn’t so helpful to me. The Flux architecture uses singletons, my current passion is Flux, I am far from the stage of mastering Flux nevermind re-architecting it.

Further research was educational. I found this very clever way of using the new ES6 Symbol() function to enforce a single instance of an ES6 class. I have to admit it took me quite a while to understand it. When I did (or thought I did at any rate!) I was impressed. But then every time you wanted to use a Flux Store, you would need to include an additional line of code as well as the idiomatic import statement — something along the following lines:

import Singleton from './Singleton.js';
let instance = Singleton.instance;

I wasn’t convinced so I looked harder and here is a summary of how my ES6 AppStore.js turned out:

Having defined the AppStore class by extending Store, I then create an instance of AppStore at line 15. This instance is my singleton and is then used for the Flux Store switch statement. It is the singleton instance rather than the class that is exported from my module at line 34.

It was a bit of a fiddle to get there but this approach seems to be working for me. Of course there are plenty more challenges of using ES6 with Flux and React and I will try to cover some them in due course.

Hail hail.

Show your support

Clapping shows how much you appreciated Colin Fallon’s story.