Angular 2 v React with Flux: Dawn of Component Driven UI

I was gonna make a funny blog post comparing Angular 2 and React, satirizing the horrible Batman v Superman movie, but after seeing Captain America 3, I felt bored and disappointed by comic book movies in general and will now acquiesce to writing a standard bland post full of technical jargon.

However I will intersperse funny Homer Simpsons gifs like this to keep us entertained:


Look at it go!

Anyway, seeing how both React and Angular are by far the most popular MV-whatever frameworks in today’s front-end web dev landscape, I’d thought I try a little experiment and do a shoot-out between the two. Having not worked with either since at least the end of last year (with Angular, an even longer time), I figured I’d give myself a little refresher, while also getting a real in-depth critique of their comparable strengths and weaknesses. If you happen to be lazy and have no attention span like most people these days, please scroll to the bottom for a TL;DR summary of my fleeting assessment.

The App

I recreated the iPad version of the iOS Notes app with both libraries/frameworks.

You can view the React version here: React Notes
And the Angular 2 one here: Angular Notes

Also please check out the actual code on Github: Repo

OK, this was a very boring choice to recreate, but I’ve been using that app a lot lately. It’s also trivial enough where I don’t have to implement too much logic but also just enough to give me a taste of what it would feel like to actually use it for something more substantial.

The app, if you are unfamiliar, is simple. There’s an editable text area in the middle. Click on it and write something. It saves. Click on the pencil icon in the corner to make a new one, the trash icon to delete the current one. Click on the Notes button in the top left to open a sidebar to show a list of all your notes. Click on a note to see and edit it.


Not much to it.

React with Flux

I started out writing the app first with React, since I actually have experience using it. I’d never used it with Flux architecture however, so I went and took a look at the official React tutorial with Flux. I lifted some of the boilerplate code from the tutorial into the project (namely the dispatcher implementation, which is just a very basic Observer object with promises).

If you aren’t familiar with it, Flux is an architecture pattern promoting an uni-directional flow of data. I’m not going to give any more than a cursory summary of Flux, because you can look it up yourself, but basically, Flux can be broken down into four discrete parts: actions, dispatchers, stores, and views.

Actions are concrete directives an application can take. Actions flow into a dispatcher, which act as a centralized event bus. The dispatcher then notifies stores (which have previously registered callbacks to the dispatcher). Stores, which handle application state and hold data, then emit change events which are listened to by the views (which are React components in this scenario). The views then of course update and re-render what’s shown to the user. Any further actions are triggered by the view, and the uni-directional flow of data is restarted.

var _callbacks = [];

export default class Dispatcher {

 
  register(cb) {
    _callbacks.push(cb);
    return _callbacks.length - 1;
  }

  dispatch(payload) {
    _callbacks.forEach((cb)=> {
      cb(payload);
    });
  }
}

The dispatcher class from Facebook is a primitive observer, that simply registers callbacks and invokes all of them at once in a single dispatch (no custom events). I removed their promise implementation as there were no asynchronous data calls in my app.

  constructor() {
    super();

    AppDispatcher.register((payload)=> {
      var { val, id, actionType } = payload.action;

      switch(actionType) {
        case NoteConstants.CREATE:
          Notes.create(val);
          this.emit(CHANGE_EVENT);
          break;

        case NoteConstants.UPDATE:
          Notes.update(id, val);
          Notes.currId = id;
          this.emit(CHANGE_EVENT);
          break;

        case NoteConstants.DESTROY:
          Notes.destroy(id);
          let notes = this.getNotes();

          if (notes.length) {
            Notes.currId = notes[0].id;
          } else {
            Notes.currId = null;
          }

          this.emit(CHANGE_EVENT);
          break;

       // more switch cases
      }
    });
  }

A store registers a callback to be triggered by the dispatcher. When invoked, it uses a switch case to process the appropriate action. The store then emits an event (subclassing Node’s Event Emitter) which is listened to by a view.

All in all I found Flux to be a very sound paradigm. I don’t think it’s the end and be all of ways to build your app, but it’s certainly a well designed and structured one. Like most JavaScript design patterns, it relies heavily around the pub-sub/observer pattern, which is definitely my preferred method of communicating between distinct objects. The uni-directional data flow and actions are also enticing to me because you are breaking down and structuring the app into very concise and linear segments, making it very obvious as to what’s happening on a high level.

However, as nice as I found the precision and structure of Flux to be, it was ultimately overkill for an app of this size. Since this app doesn’t have many actions/events, you don’t really to need to have concrete action directives or a centralized dispatcher for event notification. Initially I was not going to use Flux and simply use a singular instance of the Node.js Event Emitter, which would have been sufficient for what I needed to accomplish. If I had decided to have gone that route, I would have avoided writing a lot of boilerplate plate code, but it would probably not be sufficient if the app grew in size.

An alternative pattern to Flux is Reflux, which is a somewhat parsed down version of it, removing the singleton dispatcher and instead moving that responsibility to the action itself.

What I wanted to emphasize is that Flux is definitely not a framework, simply an architecture pattern, and it’s up to you to implement it yourself. If you want an out of a box solution for your project, Facebook has made their implementation available.

As for React.js itself, I feel mostly warm and fuzzy about it. The main issue I have with it is I’d very much rather have automatic two-way bindings, and prefer Angular much more in that regard. I know two-way binding is an anti-pattern in regards to Flux, but I really hate, for example, having to always include a handler function on an HTML input’s change event simply to just manually sync data on the model/state.

Also, I’m not too big of a fan of JSX and don’t care for mixing my HTML templates with JS (and I know you can have independent JSX files, but it’s much more annoying) as it conflicts with the separations of concerns programming principle that was beaten into my head so many years ago, but I’m coming to terms with it. Also, seeing how web components promote sticking the Javascript, HTML, AND CSS all together, it just seems like things are trending inevitably in that direction.

What’s cool about React ultimately, is that unlike Angular or Ember, it’s really just a view controller (and a really fast one because it’s use of virtual DOM). You could for example use it with Backbone, taking away the shitty manual Backbone View and replacing it with React, all the while still using Backbone models, collections, and the router. React is really flexible and un-opinionated in that regard. I mean in the React tutorial they freaking use jQuery for Ajax!


Stay with me

Angular 2

Although the majority of the app logic was already written (with the majority existing in the store), converting it to Angular 2 was somewhat challenging because of my lack of familiarity. Even though I have a fair amount of experience with Angular 1, 2 is completely different.

Gone are controllers–everything is now component driven. Templating syntax is also different, with event bindings and familiar ‘ng’ directives getting an overhaul.

Compounded with severely lacking documentation (which is expected for a beta version), with the only significant amount of anything geared exclusively for TypeScript, it took a little bit of time to figure out. It’s actually fairly apparent that Angular 2 was created with TypeScript in mind, notably making use of Typescript’s decorators for everything. In fact, the docs come only in three versions: TypeScript, plain ES5 (OK?), and Google Dart (LOL).

Despite all the changes, if you are already familiar with component driven UI development, it should be pretty straight forward. Also, if you already know Angular 1, all the familiar ingredients still remain: directives, services, providers, dependency injection, etc.

  @Component({
    selector: 'my-app',
    template: `
      <div (click)="closeSidebar($event)">
        <notes-header></notes-header>
        <notes-sidebar></notes-sidebar>
        <notes-note></notes-note>
      </div>
    `,
    directives: [Header, Note, Sidebar],
    providers: [NotesService]
  })
  export default class AppComponent {
  // .etc

Example of the decorator for the app level component. Decorators appear above ES6 style classes as metadata to dictate class functionality.

Somehow I was able to mostly keep everything in plain ole’ ES6 JS (keeping the .js file extension) with the help of several Babel plugins that allowed the usage for the decorator syntax and a couple other TypeScript style things. Notably, injecting a service/provider into a component won’t work unless using TypeScript’s function parameter typing.

One of the big changes in Angular 2 is that there’s no more $scope. You simply add properties to the class instance, and they magically are processed by the templating engine. I’m actually not sure if they completely revamped the internals of the framework, and whether or not it still relies on the digest cycle along with dirty checking for re-rendering.



 <ul class="sidebar" [class.show]="isOpen">
    <li *ngFor="let note of notes" [class.selected]="note.isSelected" (click)="selectNote(note)">
      <span class="note-name">{{note.name}}</span>
      <span class="note-date">{{note.date | sidebarDatePipe}}</span>
    </li>
 </ul>


Example of new templating syntax. Note the changes to ng-class, and ng-repeat.

Architecturally, Angular 2 seems rather the same than it’s predecessor. Instead of nested controllers passing around data, you have nested components passing around data. Gone are modules, instead you create your own modularity using the ES6 native module system. In fact you could simply bypass the injector completely for services, though the Angular team doesn’t recommend it.

Communication between disparate components are accomplished in a variety of ways, either passing parameters through parent/child components similarly to React, or relying on a event system or shared service. For my app, I simply chose to go with the shared service route, with the store for the React version basically being transformed to a service. Angular 2 also includes their own version of an event emitter, and I utilized it in pretty much the same way I did for the React store.

There’s plenty of other new features that I haven’t tried with this demo, such as inputs/outputs on components. Additionally, the Angular router, http, animations, forms, and others remain to complete the full-fledged framework.


Almost done!

Verdict

React and Angular 2 are both good options for starting a new project utilizing component driven UI development. Neither is better than the other, and it’s simply up to you whether to decide what you prefer or feel more comfortable with.

Personally, I would give React the edge, simply because Angular 2 is still in beta mode, and it’s questionable whether or not it’s production ready. React also allows for more flexibility, allowing the developer more freedom to cherry-pick whatever libraries/packages they feel most suitable for their needs, which ultimately I feel is more aligned with the temperament of JS-based development.


So much to choose from!

React Pros

  • library and not a framework, only a view layer and more agnostic because of this
  • fast rendering via virtual DOM
  • established, larger community usage, and trending upwards
  • Flux is a proven architecture pattern with a lot of supporters

React Cons

  • flexibility might be problematic for someone who’s less experienced
  • if using Flux, user has to implement it themselves
  • JSX could be unattractive for some developers

Angular 2 Pros

  • monolithic framework, provides everything you need to build an app
  • two-way binding
  • plenty of HTML directives which would have to be otherwise manually coded in React

Angular 2 Cons

  • still in beta mode, poor documentation
  • monolithic framework, less flexibility
  • ostensibly forced to use TypeScript
  • very different from Angular 1, might be a steep learning curve for some


Goodbye!

Advertisements

On Style

Embed from Getty Images

I’m pretty sure there’s a lot more to life than being really, really, ridiculously good looking. And I plan on finding out what that is.

– Derek Zoolander, Zoolander (2001)

Consulting exposes you to so many codebases and so many coding styles. This is especially the case when it comes to coding in JavaScript, a language so expressive and fluid that there are so many ways to accomplish the same piece of functionality.

JavaScript style guides abound. In this post, I would like to discuss some of the benefits of using or implementing your own style guide, as well as a few things I’ve learned traversing the bardos of development. While some of these insights are specific to coding in JS, most extend to coding in general.

Don’t rock the boat (without a chat).

Consultant or not, a good developer is a ninja in the codebase. (This is one of the most tired metaphors in development, but I could think of no better term, aside from secret agent). Do a good job and make it seem like you were never there.

Don’t use seven words when four will do. Don’t shift your weight, look always at your mark but don’t stare, be specific but not memorable, be funny but don’t make him laugh. He’s got to like you then forget you the moment you’ve left his side.

-Rusty Ryan, Ocean’s Eleven (2001)

The best code reads as if it was written by a single person. That single person is the team. As an engineer, your aim should never be to write a piece of code so slick that the code around it cowers in unworthiness. Sure, it can and should be awesome, but it should remain in context. Try to mimic syntax and architecture choices. As a fellow team member, you always want to strive to improve the code, but make it seem like they wrote it themselves.

If the code is so horrific, organize a team chat before you decide to change how everything is done. A style guide that everyone references and adheres to should be the goal of that chat. Linting is also your friend. JSHint or JSLint can be customized to your team’s development standards and be included as part of the build process.

Bad code costs more than money.

Sloppily written code slows down development. As a developer, most of your time is spent reading other people’s code. Inconsistent spacing and syntax, aside from questionable architecture, is slower to read and comprehend and slower to debug. Onboarding new team members takes longer. The more time spent reading and debugging rather than coding just makes development cost more. Frustrating code makes people grumpy. We don’t want to work with grumps.

Don’t be too clever.

I’ve spent some enjoyable evenings working through coding challenges on Codewars. One thing I’ve noticed, however, is that the top rated solutions to challenges are always obtuse one-liners. They are very clever, blocks of code that read like haikus. They’re beautiful. Still, if you came across it in your codebase, would you understand what the code was doing right away? Maybe it would take 10 seconds until comprehension versus an instant. Over time this adds up. As minification is a standard part of development, brevity at the cost of readability doesn’t make much sense.

Write to be read.

Keep it simple. Like with prose, the best code is simple and clear.

Annotations and comments should be minimal. For annotations, descriptions should be simple, yet beefy enough that if turned into actual documentation, the reader would get the point easily without referencing the body of code itself. Comments shouldn’t be too necessary. If you find yourself writing lengthy comments explaining your code, it needs refactoring.

Descriptive variable and method names help decrease the need for comments. For example, I’m not going to remember what x stands for 40 lines later, but minLength does the job. Variables should be nouns. Method and function names should have action names. If not, it is easy to expect a method to be some property.

Don’t overload the buffer.

An overloaded buffer slows us down. Like CPUs, humans have limited short term memory. Try breaking your code into smaller units. Limit the amount of things a person has to remember to understand parts of code. Methods should just do one thing. If you have a bunch of conditionals, keep code within the initial if / else if clauses brief, and leave the complex bit inside the final else. This way, the reader has to remember less.

Write to be tested.

Keeping methods short and focused also serves another purpose – unit testing. Focused methods means easier to write unit tests. The faster I can get through writing unit tests the happier I am.

And finally…

In the end, you are writing code for other people – other developers, your team, your users, and finally your future self. Keep them happy, then you will be happy.

billandted

It doesn’t hurt to have a boy scout mentality, to leave any place you visit cleaner than when you found it. When this habit is ingrained, it becomes effortless to subtly improve code every time.

Save poetic experimentations for personal projects. However, there is always the chance your future self that may look back on it and have no idea what you did.


(A quick recommendation for all you lit lovers out there: If Hemingway Wrote JavaScript. Angus Croll’s book is a fun read and a testament to the expressiveness of JavaScript.)

I Ching App with Polymer and ES6

We recently developed an I Ching app utilizing Polymer and ECMAScript 6, and I wanted to present some of my thoughts on the development experience using these technologies.

This is not meant to be an exhaustive tutorial on either Polymer or ES6, as you can simply search and find a myriad of helpful tuts on the web, but rather a short reflection on how using these frameworks/features can enhance (or hamper) your front end based web applications.

You can check out the app here: I Ching

And also check out the code on: Github

First of all, in case you’re unfamiliar, the I Ching, or Book of Changes, is an ancient Chinese divination text. Divination is a way to gain insight into a question or situation via ritualistic or “occult” (or some might say spooky like voodoo or some creepy, weird crap like that!) means. Famous examples of divination are astrology or the tarot.

Anyway, to consult the I Ching, one uses one of two techniques (we implemented the coin technique) to produce six lines, either solid, broken, or changing – meaning either a solid line “changing” into a broken line or vice versa.  These six lines, read from bottom to top create a numbered “hexagram”.  The actual I Ching text is simply a compilation of these 64 hexagrams with corresponding bewildering and befuddling commentary for each (I challenge you to understand what it means!).

So the long and short of it is you ask a question, throw your coins six times to get a hexagram, look up the hexagram in the text, and read the corresponding commentary for your answer.  Simple enough, right?

Polymer, if you haven’t heard of it before, is a front end framework which is essentially a Web Component polyfill with some extra features thrown on top.  I’ve been intrigued by Web Components for quite while ever since I’ve came across them a couple of years ago and how they will potentially dramatically change the way we architect and develop code on the browser. I won’t go into too much detail about them, as you can simply read up about them yourselves, but they are a future collection of standards that are still getting approved by W3C and are slowly being adopted into modern browsers. Chrome as of this date is the only browser to have complete support for Web Components.

Web Components revolve around custom HTML tags, Shadow DOM, HTML imports, and the template tag.  Think of them as fully encapsulated UI features that can be simply inserted into your web page by including a custom tag in your HTML, kind of like a jQuery plugin.  Here’s a quick and dirty example.

Let’s say we want to make a new component called iching and use it in our site:

<head>
  <link rel="import" href="path/to/component/iching.html">
</head>

<body>

  <!-- This will do something -->
  <iching></iching>

</body>

The component’s functionality would be triggered simply by including the custom tag, while the components corresponding code is pulled in via the HTML import as seen above in the head.

The code in the iching.html file would look something like this.

<style>
  button {
    color: red;
  }
</style>

<template>
  <button id="myButt">Clicky</button>
</template>

<script>
  document.getElementById('myButt').addEventListener(function(){
    console.log('clicky');
  });
</script>

That code doesn’t really do much of anything, but it conveys the basic paradigm of Web Components. The markup contained in the template tag would be inserted into the iching tag, with the corresponding scripts and styles (which can utilize external files opposed to being inline just as easily) going to work on it.

The really cool thing about all of this is that the markup within the component is only accessible (well almost, there is a loop hole) by the scripts associated with the component, aka Shadow DOM. The styles rules would also only be applied locally. So basically we get fully separate and encapsulated UI pieces that don’t clash and step on each other’s toes and a much cleaner HTML file free of endlessly nested divs. Yay!

The one necessary feature Polymer added that doesn’t exist in the Web Components standard is data binding in the template tag to dynamically render views (more about this later).

As far the actual application goes, almost all of the logic is written entirely in the front end, with the only back end piece being a simple service that returns the hexagram commentary pulled from a JSON file.

The app is broken down into several different logically separated components. I decided to include all the styles and scripts associated with each component in a separate file because inline makes me feel a bit weird and uncomfortable. Each component communicates with one another through custom events running through a global event bus/emitter.

Easy peasy right?

Everything was going smoothly until I decided I wanted to use ES6 syntax. That’s when things got tricky.

ES6 is the lastest version of ECMAScript, and introduces a whole slew of features to the JavaScript language that will make JS coding look and feel a lot different.

Right now most of those features have only a smattering of support across modern browsers (mainly Chrome and Firefox), so a transpiler is required to write code in that syntax. I decided to use Babel over Google’s Traceur admittedly just because it seemed trendier and had a nicer looking site.

I think ES6 is great and adds a lot of useful features that improves JavaScript coding. Though most of the features we ended up using were quite trivial such as let, const, arrow functions, enhanced object literals, and rest/spread. More advanced features weren’t used like generators or proxies (which is not even able to be translated in ole’ ES5).

The main thing that made things difficult with Polymer was using ES6 modules. Babel won’t transpile ES6 modules directly into ES5 but instead into modern module formats such as CommonJS or AMD. I decided to go with CommonJS which meant using Browserify. This was all handled with Gulp running Browserify with a Babel transforms.

Because of the component application structure, it seemed more logical to create separate bundles for each component rather than a singular application bundle. This, however, failed to work as each component needed to share a global module (the event emitter). Creating separate bundles meant creating duplicates instead of the shared module, which made the app incapable of sharing state between components, so one global app bundle was necessary.

Polymer requires their components to be registered with JS in their HTML imports file, but each component referencing the same bundled JS file would not work. Instead, each component had to be registered from one application entry point file. This caused problems on Firefox and Safari because the bundled code would run before the Polymer source JS code (pulled in as a HTML import from every component’s HTML file). As a result, for local development, we had to run Polymer’s Vulcanize build tool which inlines every HTML import file into the main HTML file (which is ideal in a production environment to reduce network requests).

All in all, getting all this stuff to work together was a huge pain in the ass, and Polymer and the ES6 transpiler seemed very unnatural together.

In general, I like how Polymer allows us developers to use Web Components in browsers that still don’t support them. My main complaint with them is that their templating engine (for data binding) is pretty limited compared to something like Angular’s (which they state is for performance reasons in their docs). Nested object properties won’t auto-render on change, so you manually have to trigger the event in the code, since they don’t use dirty-checking like Angular. Also, template braces must encompass the whole attribute or content of a tag, which annoyingly makes simple tasks such as adding a class (which in both Angular and Handlerbars, with helpers, able to be confined in the template logic) resort to DOM querying.

I have to admit I initially wrote the code in plain jQuery, and it was a whole hell of a lot easier to get it working. Of course this app is quite tiny compared to most things, and a huge jQuery app would get out of hand really fast.

It was a fun experience to build something in a new way that I hadn’t tried before. On the other hand, a part of me feels like ultimately all these frameworks are just variations of accomplishing the same thing.

I mean at the end of the day, all that matters is product right?

I guess it all depends on who you ask.