I’ve stopped writing my own JavaScript framework because …

This post should have been written back in February! But I’m bad at blogging …

Rolling my own solution was a great way to quickly get up to speed on modern JavaScript syntax and best practices. I think it’s really the best way – for me. But in the end I was never going to be confident in it enough to release or suggest anyone else use it.

I was building more apps and the realization that someone was going to come behind me and maintain these things started to hit home. I’ve been in this situation before, and long term product maintenance and support wasn’t something that I wanted to get into again.

And I was job hunting. “No, I’ve never used React/Angular but I wrote my own thing …” was going to go anywhere. So I quit cold turkey and started picking up React. I’d based a lot of my methodologies on it anyway.

So that’s where I’m at now. As an e-learning developer at Red Hat, I don’t bang out code all day, but React has been great for producing apps very quickly. I’m really happy with it.

I’m writing my own JavaScript framework because …

This is a question that I “know” the answer to, but putting it down has actually been a pretty difficult. However, after discovering Tero Parviainen’s talk “Build You Own AngularJS,” I think I have a pretty good supporting reason.

Going back to my first post on this from April, I did it just to learn the basics of vanilla JS. Looking around too many people are learning frameworks and push code with them while not spending time to grok the core language. I didn’t want to be one of those and this is still true.

I’ve always liked to take things apart and discover what’s under the hood, it’s the best way to see inside of the black box. So that that’s what I’ve been doing – learning JS by looking at the internals (source, tutorials, etc.) of popular frameworks and reimplementing those in my own.

I’m building to learn. I’m building to discover and know how the shit gets done.

I’ve been focusing on React and Redux for the past few months, but I’ve never actually used them, learned how to use them on a real project. I need to get that experience add it to my resume. Not sure what my next project will be but it’ll be built with those tools and when I build it, I’ll know what’s in the box.

My framework is on GitHub.

This is cool …

Haven’t updated this in a REALLY LONG TIME, but progress on my framework is going well. I’ve definitely moved towards React with it and introduced ES6 with the help of Babel / Gulp.

I’m testing out child components and just coded up this little button thing. Really simple, but it’s damned cool to see how little coding it can take on the front end when properly support on the back side with framework architecture.

let counter = 0;

export default Nori.view().createComponent({

  getDOMEvents() {
    return {
      'click button': () => this.setProps({label:'Clicked ' + (++counter) + ' times'})
    };
  },

  template(props, state) {
    return this.from(`
      <div>
        <button>{{label}}</button>
      </div>
    `);
  }

});

 

RxJS based Pub/sub Eventing

An global eventing system is a pretty key piece of a full fledged MVC app. It lets you very easily separate concerns while maintaining communication between discrete parts of the application.

I’ve been using a simple event dispatcher for a while now. At the same time, I’ve had my eye on the excellent, and still way over my head, RxJS library. I had been using it for DOM / browser events, but I couldn’t wrap my head around how to connect event strings (“magic strings”) with an Observable and use that to execute commands or callbacks. Then I discovered this bit of sample code that demonstrated exactly what I wanted to do.

I hand’t looked at the Subject object before, but it does exactly what I need. And the callback / handler / command execute function fit right into the role of the subscribed onNext function.

Adapting the emitter example fit into my framework was straight forward and I ended up with a new Emitter module that replaces both my old EventDispatcher and EventCommandMap.

I’m keeping a simple map of subjects keyed to the event string

_subjectMap[evtStr] = {
 once: once,
 handler: handler,
 subject: new Rx.Subject()
 };

And whenever an event is published, this object is retrieved and the subject’s subscribers are notified. If the event was only supposed to occur once, it’s unmapped safely.

function publish(evtStr, data) {
  var subjObj = _subjectMap[evtStr];

  if(!subjObj) {
    return;
  }

  if(subjObj.once) {
    subjObj.subject.onCompleted();
    subjObj.subject.dispose();
    subjObj = null;
  }
}

Mapping to a command module was painless as well since we just need to map the execute() function to the subject.

function subscribeCommand(evtStr, cmdModule, once) {
  var cmd = require(cmdModule);
  if(cmd.hasOwnProperty('execute')) {
    return subscribe(evtStr, cmd.execute, once);
  } else {
    throw new Error('Emitter cannot map '+evtStr+' to command '+cmdModule+': must have execute()');
  }
}

Adding routes

I had a new JS project come up at work, so I’m taking time to extract my framework from the Gallery project into one that’s reusable for other projects. I should come up with a hipster name for it I suppose. Anyway, I put it on Github as App-Framework.

The Gallery didn’t need to manage multiple views and the URL routes were for  bookmarking to search results. I needed to extend my simple URL router module so that I could bind a controller function to a route change. Since I’d never done this or used a framework that did, this great post gave me a nudge in the right direction.

Setting up a route with the updated router module is pretty simple.

_router.when('/',{templateID:'test', controller:function(obj) {
  console.log('Running route: '+obj.route+', with template: '+obj.templateID);
}});

The when method will map the route (as a key/object property) to a controller function that’s run when the URL changes. Pretty handy.

My app framework utilizes commands for controller functions, so I needed create and addition utility function on my controller to map this to a command:

function mapRouteCommand(route, templateID, command) {
  _router.when(route,{templateID:templateID, controller:function executeRouteCommand(dataObj) {
    command.execute(dataObj);
  }});
}

Mapping is still simple:

mapRouteCommand('/', 'defaultView', _self.RouteInitialViewCommand);
mapRouteCommand('/1', 'test1', _self.RouteOneViewCommand);

From this point, it will call a method in the AppView to load/render/show the view.

Better Modules: Hacking my way towards modularity

“A beginning programmer writes her programs like an ant builds her hill, one piece at a time, without thought for the bigger structure. Her programs will be like loose sand. They may stand for a while, but growing too big they fall apart.

Realizing this problem, the programmer will start to spend a lot of time thinking about structure. Her programs will be rigidly structured, like rock sculptures. They are solid, but when they must change, violence must be done to them.

The master programmer knows when to apply structure and when to leave things in their simple form. Her programs are like clay, solid yet malleable.”

Master Yuan-Ma, The Book of Programming

 

After implementing the automatic namespace import thing the other day, I wasn’t happy that I needed something this like this in the first place. Locking everything behind a rigid namespace was prohibiting reusability. I trying to move forward, but my structure was getting in the way. I’m at the middle paragraph in the quote above.

I wanted to move towards something akin to AMD or CommonJS modules, but I didn’t want to add the additional complexity of a packaging system (Browserify, Webpack, etc.) to my build process (*Why? See below …). I also wanted to know more about how they worked once all of the files are packed in a big file at the end of the process.

The Modules chapter of the Eloquent JavaScript book was a perfect place to start with this. It breaks down the logic and creation of both CommonJS and AMD modules as well as providing basic require() and define() functions. Cujujs.com provides a more insight to how CommonJS modules work in practice also.

Ben Clinkinbeard wrote a great post explaining what the other end of Browserify looks like – how it packages all of the external files together in to one big IIFE and then pulls them out again.

With that, I wrote my own little module system – trying to follow what I was learning about CommonJS. I don’t want to lazy load all of the files so I chose to use a module ID. I’m still using my namespaces for this – it helps to keep them organized in a logical way. At least in my head.

A module skeleton

define('package.moduleID',
  function(require, module, exports){
    exports.myMethod = function() {};
  });

All of the code for the modules is wrapped in a function. I’m passing in the global require function and the module and exports objects. The require() function handles that (below).

The define() function was borrowed from AMD, but it’s much simpler. It stores the modules function code in an object under the ID:

function define(id, moduleCode) {
  if(id in define.cache) {
    return;
  }
  define.cache[id] = moduleCode;
}
define.cache = Object.create(null);

“Loading” a module is straight forward:

var _DOMUtils = require('nudoru.utils.DOMUtils');

The require() function looks up the ID from the define.cache, creates the exports and module objects and invokes the code. It’s also cached for performance later. The returned module is a singleton, having been cached for later use after it’s first instantiated.

function require(id) {
  if (id in require.cache) {
    return require.cache[id];
  }

  var moduleCode = define.cache[id],
      exports = {},
      module = {exports: exports};

  if(!moduleCode) {
    throw new Error('Require: module not found: "'+id+'"');
  }

  moduleCode.call(moduleCode, require, module, exports);
  require.cache[id] = module.exports;
  return module.exports;
}
require.cache = Object.create(null);

I created requireCopy() function that returns an uncached instance of the module. I’m using it for my menus when I need several unique instances of a module – one for each item.

I’m spent a few hours today refactoring my utility classes all of my components with this pattern. It’s testing out well and the resulting code is a lot cleaner. At this point, I’m not quite sure if I’m going to refactor the actual application code … But maybe I’ll feel differently on Monday.

Many thanks to Dustan Kasten for guidance on all of these module systems!

Why am I avoiding packaging?

I’m trying to keep the concat’d JavaScript file as human editable as possible. I want other people to be able to edit my code without needing to install a suite of build tools – something likely to be difficult for most people where I work.

A Tangent

While trying to figure out a problem I did something interesting in the requireCopy() function. Instead of just pulling the instance from the define cache, I created a whole new copy it with some string manipulation. I was interesting in that it did work fine, but it didn’t solve my problem so I removed it.

var funcBody = srcFunc.toString().match(/function[^{]+\{([\s\S]*)\}$/)[1],
newFuncCode = new Function('require, module, exports', funcBody);

Manipulating the function body as plain text has some interesting possibilities. It might be possible to regex the var = require() statements and make a map or perform some light dependency injection.

 

Namespacing Javascript Code for Great Good

Edit This didn’t last long! A day after posting this, I moved to a better, clearer, more modular pattern.

 

I kept my code nice and tidy while developing my app by using proper namespacing to keep it all organized under sane objects. For objects that I want to be global, I’m borrowing from Objective-C and using prefixes, so NObjThingy.

As I’m going back and fixing broken windows, I’ve taken my utility classes out of the global space and put them behind a nudoru.util.* which is great and all, but now using them is ugly

nudoru.util.ObjectUtils.method('foo');

Back in AS3 land, there was true importing of other classes. Once imported, you could access their methods cleanly. I wanted something like that.

I wrote a simple function that basically does that.

function NImport(context, libArry) {
  libArry.forEach(function(lib) {
    var parts = lib.split('.'),
      obj = parts[parts.length-1];
    context[obj] = eval(lib);
  });
}

Usage is simple

NImport(this, ['nudoru.utils.NLorem']);

Accessing also

console.log('lorem: '+this.NLorem.getText(3,5));

This approach has speed advantages since we they’re local variables and we don’t have to look them up. The usage of eval() is dirty, but it works out really well in this case.

Any thoughts on this approach? It’s solving an immediate problem for me, but has anyone else done this differently?

Templating improvements

Most of the visual elements in my gallery app are dynamically generated: menus, tags, item detail views and the grid of items. I’m using Underscore for this and it’s working out really well. I saw that their implementation was based on John Resig’s micro templates – which is a pretty interesting bit of JavaScript.

I made a few changes to how I’m working with the templates and wanted to document that here.

Put it in the HTML

Previously, my templates were in big strings in the JavaScript and were became very inconvenient to work around and update with structural changes. Placing the templates in the HTML makes a lot more sense and it’s easy to do. There are just a few things that you need to watch out for:

1. Place it in a <script> tag with an ID and a TYPE of ‘text/template’. As John describes on this micro template post, the type needs to be something the browser doesn’t understand and will ignore. Text/template is a logical choice.

Here’s my tag template

<script id="template__tag" type="text/template">
 <div class="tag"><%= tag %></div>
</script>

All of my template are in this file. I added an import into my main Jade file to integrate them into the final output.

2. The templates/scripts need to be in the <head> of your document. You cannot get to them with document.getElementByID() if not.

3. Trim whitespace from the beginning of the template source. If you indent the HTML under the script tag, whitespace will be present. When this is converted into a DOM element (at least by my method), it’ll be a Text node, not an Element node. A simple trim() will take care of this.

Simple templating helper module

I wrote a simple module to wrap retrieving the template HTML and the creation / processing of the Underscore template. This standardizes the way I work with the modules across my app and will make it easy to switch away from this system if I want to later.

I implemented caching on the first retrieval of the template HTML and creation of the template object. These can be expensive ops (especially creating the template object), so this saves a lot of time.

Example numbers …

The NTemplate.getTemplate function 1) gets the template HTML and 2) creates the Underscore template object. Iterating 10,000 times:

  • No cache: ~2218.643ms
  • Cache: ~0.3ms

 

jQuery Extraction

Relying on jQuery for DOM selection and modification still doesn’t sit right with me – It makes my feel dirty and lazy. But was incredibly convenient during the initial build of the gallery app since it allowed me to quickly “sketch” out functionality.

I’m using this post to document the changes required as I refactor jQuery out of my application let some decent DOM code in. I’m adding new utility functions to my DOMUtils file.

Quick lessons learned – I didn’t prefix my jQuery variables in any special way. Looking back I need to do this next time. Something simple like “_$varName” would have been handy. However, it’s trivial to search the project for $’s to find library calls.

Element Selection

Generally, I’m selecting elements with their ID, so this is just a simple switch to document.getElementByID(). I needed to go back up and update my RxJS observers, because these were listening to jqEl[0] to get the HTML element rather than the jQuery object. All of my JavaScript animations are handled by GSAP which takes either HTML elements or jQuery objects as arguments.

More complicated sections can be handled by the element.querySelector or element.querySelectorAll methods. Note that the latter returns a node list (array) of all matched elements. If know there is only one, you just need the first element.

So this:

_mainSearchInputEl = $('.grid__header-search input');

Becomes:

_mainSearchInputEl = document.querySelector('.grid__header-search > input');

Be aware: there are differences in the older get* functions and the new query* functions – both in what kind of node list they return and performance.

Viewport metrics

Whenever the window is resized or scrolled, I’m firing off an event (to a command) with the new dimensions. This is used to realign the header and footer to the new size.

Currently, I’m using this:

_currentViewPortSize = {width: $(window).width(), height: $(window).height()};

But this is just as simple:

_currentViewPortSize = {width: window.innerWidth, height: window.innerHeight};

Because of the structured needed to create the drawer for the mobile view, I’m measuring scrollTop and scrollLeft on the div that contains the gallery grid, not the body element:

var left = $(_mainScrollEl).scrollLeft(),
    top =  $(_mainScrollEl).scrollTop();

Becomes:

var left = _mainScrollEl.scrollLeft,
    top = _mainScrollEl.scrollTop;

Element Sizes

Rather than using $el.height() you can use el.clientHeight. el.offsetHeight returns he height including padding, borders and scroll bars.

Setting HTML

From:

$el.html('<p>some html</p>');

to:

htmlEl.innerHTML = '<p>some html</p>';

Adding and removing classes

http://youmightnotneedjquery.com/ provides functions for adding and removing classes. I added this block to my DOMUtils functions:

hasClass: function(el, className) {
  if (el.classList) {
    el.classList.contains(className);
  } else {
    new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className);
  }
},

addClass: function(el, className) {
  if (el.classList) {
    el.classList.add(className);
  } else {
    el.className += ' ' + className;
  }
},

removeClass: function(el, className) {
  if (el.classList) {
    el.classList.remove(className);
  } else {
    el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
  }
},

toggleClass: function(el, className) {
  if(this.hasClass(el, className)) {
    this.removeClass(el, className);
  } else {
    this.addClass(el, className);
  }
}

 Adding and Removing DOM Nodes

All of the nodes that I’m adding to the DOM are the results of an HTML template from Underscore.

Starting with this …

var tagel = $(_tagTemplate({tag: tag}));
parentEl.append(tagel);

The first problem is that the result from the template is an HTML string, not an element. The string must be converted to an HTML element before it can be appended to the DOM.

The DOMParser method looks like a great solution, but in testing, I found that it has issues with IE9. I found a nice little technique on a StackOverFlow tread that I turned in to a function:

function HTMLStrToNode(str) {
  var temp = document.createElement('div');
  temp.innerHTML = str;
  return temp.firstChild;
}

And this now works:

var taghtml = _tagTemplate({tag: tag}),
    tagnode = HTMLStrToNode(taghtml);

parentEl.appendChild(tagnode);

Comparatively, node removal is straightforward

parentEl.removeChild(el);

 Wrapping an element in another

Pretty easy in jQuery:

$(el).wrapInner('<div class="floatimage__wrapper" />');

To do it without jQuery, we leverage the HTMLStrToNode function above and come up with:

wrapElement: function(wrapperStr, el) {
  var wrapperEl = DOMUtils.HTMLStrToNode(wrapperStr),
      elParent = el.parentNode;
  wrapperEl.appendChild(el);
  elParent.appendChild(wrapperEl);
  return wrapperEl;
}

Usage is easy:

DOMUtils.wrapElement('<div class="floatimage__wrapper" />', el);

Finding the closest match

jquery’s closest() function comes in really handy. I found a good native solution on this StackOverFlow thread that includes vendor prefixes since the matches() function is still relatively new.

 

 

 

Moving to a JavaScript Application Architecture

Preface

From 2003 to 2011 I became a pretty decent ActionScript developer. Starting with single frame movies then to fully structured MVC applications.

With my team, I’d spent a lot of time looking at two powerful frameworks   Cairngorm and RobotLegs. I really liked RobotLegs, and being my first introduction to dependency injection – was really intrigued.

I ended up writing my own framework based on RobotLegs called Nori. It was pretty slick – mediators, contexts, mapping, Signals, views and tons of interfaces (any DI system has). I only used it for a few projects before a career change and a transition to consulting and design / prototyping.

Fast forward a few years and I’m trying to break into coding again with JavaScript. I’d done a fair bit of JS dev in 2000-3, but really hadn’t paid much attention to it since then.

Holy shit!

I have a lot to learn.

Writing my own …

Over the past two years, I’ve spent (too much) time looking for a starting point – Angular, React, ExtJS, Ember, Dojo, etc. I didn’t have a project so I just cycled around in this framework limbo.

Then I found a project. Time to get realz …

My team needed a gallery to showcase our work and provide simple case studies to prospective clients. I’d build something similar to this before, in haXe, that was based on Microsoft’s Pivot experiment. I decided to recreate it but with more of a Pinterest influence.

The front end would be a fluid, responsive JavaScript application that also worked on our primary browser, IE9. It would also scale to mobile phones and be accessible though our corporate GOOD app.

The back end would use SharePoint lists. SharePoint is a decent backend for database challenged teams in big companies and it also comes with a “free” content maintenance system.

I couldn’t waste time researching frameworks anymore, and I had a strong desire to actually learn the language, so I decided to writing my own. My basic task list is/was:

  1. How the hell so I set this up and what build system do I use?
  2. How do I architect this thing? How can I best create class/subclasses and implement the command pattern?
  3. How do I create a global event system (pub/sub) system with command mapping?
  4. What’s cutting edge? FRP, Reactive programming and RxJS!

The project started in November as a part-time/between-other-work project. I’m wrapping up the front end now with the back end still to go. My purpose for this post, is to document my thought process and hopefully solicit some feedback on my approach.

Here’s a break down of what I’ve learned and done over the past few months. I know that it’s nearly useless without screen shots (source code on GitHub) but I’m working on that.

The project source is available on GitHub.

Project setup and build options

No respecting front-end dev writes HTML or CSS anymore. Attending Meet Ups around Charlotte, I saw how people were using Sass and Jade tempting. I have give the credit to the talented Tessa Harmon for introducing these to me at a Charlotte Front-End Developers meeting.

Both of these preprocessors resonated with me as being a much more efficient way to produce CSS and HTML – variables and mixins, oh my! The biggest challenge is working with these in a typically Windows based corporate environment. Lucky, I was able to get a Mac at work. I’ve been developing prototypes with Jade and Sass for a few years at this point with the excellent CodeKit app. On the Windows side, Prepros looks like a great alternative.

I’ve found the indented syntax style of Sass to be the best fit for me. Not only does it go very well with the style of Jade, it’s saves a ton of typing. The fewer braces and semicolons you need to worry about, the better.

I’d seen Grunt but hadn’t used it. Reading articles. like this one from Chris Coyier, really simplified the concepts. It was pretty easy to get it all up and running and enabled a much simpler build process than I was able to achieve with CodeKit. So I have SASS + Jade processing, CSS linting, CSS minification, JSLinting, JS concatenation + minification and live reload all working well.

Being able to work with JavaScript in a modular way, split across many files, is a critical workflow feature. I was used to splitting up my classes in to single files and I was able to preserve that with this process thanks to these tools.

Other libraries

I went back and forth on jQuery. On one hand, the efficiencies gained by utilizing it’s selector and DOM manipulation engines cannot be underestimated, but on the other – I wanted to learn how to do this on my own. In the end, I decided to use it, it just saves too much time.

Having to support IE9 meant that CSS animations were not possible. While developing in Flash, I relied heavily on the awesome GreenSock animation platform and with a JS version available, it was a no-brainer.

I’d struggled a bit with the view styling. Do animations count as “style” (CSS) or functionality (code)? I didn’t have a choice in this situation, but now I’m firmly on the side of code – the control and possibilities presented by JS animation libraries over CSS is too much to ignore.

To handle HTML templating, I compared Mustache.js and Underscore.js. Mustache provided a nice single purpose solution, but Underscore did all I needed it to plus provided a ton of additional functionality that I might need later on. So I went with it.

What’s next

  • Clean up my CSS classes by implementing the BEM system
  • Optimize my Grunt file.
  • Learn more about git and GitHub

OOP / classes, subclasses / structure / commands

I came from a strongly classed development environment. So naturally I wanted to recreate that in JS. But JS doesn’t do classes but it does do objects. I couldn’t use ES6 because of IE9.

Finding way to create namespaces was key and paired with the revealing module pattern, made for a great solution. I implemented the approach Kenneth Truyers documented for my application.

I do have a few global objects, for utility classes, but generally my application structure is:

All of the major parts of the app (bold, above) are constructed like this:

APP.createNameSpace('APP.AppController');
APP.AppController = function () {

// private var
// private methods

return {
// public api
};
}();

These are effectively singletons.

Commands

Both the Cairngorm and RobotLegs frameworks handled the heavy lifting of controller duties in commands. The separation of core functionality outside of the controller made extending the app very simple. Command classes are single responsibility, small and have access to all of the actors in the application.

My commands have a single entry point, an execute() method, that takes one object parameter for passing in data. In my framework, commands are only invoked in response to an event. For every command there is a corresponding event that is published from somewhere in the application. This is discussed in the Events section below.

In my current implementation, they’re synchronous, but I can see needing asynchronous in the future as I’m loading data from sources.

Pattern for subclasses – commands and subviews

To implement commands and sub views, I had to seek an alternate class/object creation pattern. Creating multiple instances of objects with the module pattern isn’t entirely straightforward. Although there are several methods of extending new objects with the properties of an existing object (jQuery’s extend(), etc.), the private methods of the closure aren’t readily accessible in the subclasses. Composition would be been a way to handle this, but I choose a different approach.

I discovered Eric Elliot’s Fluent JS talk on prototypal OO. His StampIt pattern was just what I was after, but I wanted a more accessible approach. I stumbled on an article by Jake Lucas which described a method just like Eric’s, but broke it down so that it was easier for a noob, like myself, to understand.

Using commands as an example, I have this as the abstract command class

APP.AppController.AbstractCommand = {
  state: {},

  methods: {

    app: APP,
    appController: APP.AppController,
    appModel: APP.AppModel,
    appView: APP.AppView,
    eventDispatcher: APP.EventDispatcher,

    execute: function(data) {
      console.log('Abstract command executing with data: '+data);
    }
  },

  closures: []
};

And then I create a new command instance by using a factory method to create a new object and then override the execute method of the new command

APP.createNameSpace('APP.AppController.ItemSelectCommand');
APP.AppController.ItemSelectCommand = APP.AppController.createCommand(APP.AppController.AbstractCommand);
APP.AppController.ItemSelectCommand.execute = function(data) {
  
// new implementation

};

A few disadvantages for this approach:

  1. Alternate coding style compared to the modules
  2. Lots of boilerplate to create the objects

What’s next

  • I’m not entirely satisfied with my approach on commands and subviews. I want to look at other ways to subclass modules.
  • Look at ES6 transpilers so that I can leverage these features now.

Event system (pub/sub)

A publish/subscribe system is key for maintaining loose coupling between components of the application. For my app, I wanted to create a global system similar to the EventDispatcher in AS3.

When I last coded AS3, I was heavily using Robert Penner’s Signals implementation over native events. His approach won me over especially consider the fragility of the “magic strings” naming of event types. They were easier to work with and implement than native events. There is a JS port of it that I initially used, but later decided that it wasn’t worth the additional overhead.

Looking to simplify my approach, I found a great example from Michaël Duerinckx on his blog. It demonstrated exactly what I needed and was straight forward. I created an object APP.Events.Events that stored all of my event strings as constants.

Generally, I’m using events to invoke an instance of a command class – there is 1:1 relationship – the APP.Events.ITEM_SELECT event has a corresponding APP.Controller.Command.ItemSelectCommand associated with it. This mapping is handled by an EventCommandMap class.

I had implemented a command mapping solution in my Nori AS3 framework that was based on Joel Hook’s Signal Command Map for RobotLegs and Omar Gonzalez’s for PureMVC. I greatly simplified my original approach and with some helpful hints from a friend, had it working with my EventDispatcher.

In the controller, commands are mapped like this:

mapCommand(APP.Events.ITEM_SELECT, APP.AppController.ItemSelectCommand);

And trigged like this (‘id’ being wrapped in an object and passed to the command’s execute() method):

_eventDispatcher.publish(APP.Events.ITEM_SELECT, id);

The command map handles determining what command class should be instantiated and executed.

What’s next

FRP!

Future State: FRP, Reactive programming and RxJS

Functional programming is the current hotness in JavaScript. Honestly FRP is still kind of a dark art to me, but it’s clearing up thanks to excellent articles explaining the concepts, libraries like RxJS from Microsoft and tutorials from Netflix.

While I’m not ready to architect a reactive application, I am using Array methods forEach, map, filter, etc. pretty heavily. There are some performance issues with these, but it’s completely worth it for code readability. I’m only dealing with up to hundreds of objects so I’m not likely to see these in my current implementation. But it does make filtering my data more sane:

function filterProperties() {
  _filterProperties.forEach(function(filter) {
    var props = [];
    _data.forEach(function(item) {
      if(item.hasOwnProperty(filter.filter)) {
        var itemPropVal = item[filter.filter];
        if(typeof itemPropVal === 'string') {
          props.push(itemPropVal);
        } else if(itemPropVal instanceof Array) {
          props = props.concat(itemPropVal);
        }
      }
    });
    filter.data = ArrayUtils.unique(props).sort();
    filter.menuData = getDataFormattedForMenu(filter.data);
  });
}

I’ve implemented RxJS for some events – primarily execution environment: browser, mouse, touch, etc. The pure simplicity of this approach is really cool. Just cool.

_itemOverStream = Rx.Observable.fromEvent(_containerEl[0], 'mouseover')
  .filter(filterForMouseEventsOnItems)
  .map(getMouseEventTargetID)
  .subscribe(function (id) {
    selectItemByID(id);
  });

I need to delve deeper in to this, replacing my events and turning my classes into RxJS emitters.

Wrap up

So that’s been my learning path for the past few months. I’ve omitted a few dead-ends and research for brevity (ha!). I still have the back end of this to work though, but I’ve a similar setup at another company so it shouldn’t be that difficult.

I’m going to write a few more posts on various aspects of this – my view components and looking at AMD/CommonJs or WebPack.

If you made it this far, please comment! I’m seeking advice on my approach and rationale.

Thanks for reading.