Wednesday, April 30, 2014

Embular Part 6 - Two Paths Up The Same Mountain

Years ago when I was learning kung fu, my Shifu would talk about kung fu and tai chi as "two paths up the same mountain". One path was external and physical. The other path was internal and introspective. That was to say that in both kung fu and tai chi you were starting from two difference places, but you were on a journey to the same point. When you reached that point, the only logical choice was to continue down the other path.

I feel that Angular and Ember are nearing this point. And I think they're reaching it at pretty much the same time. Simply cresting the mountain isn't enough; Now it's time for both frameworks to take a trip down the other side.

It seems to me that Angular's path has been primarily driven by a desire to create a highly extensible, clean, simple, concise API, to allow developers the power and freedom to accomplish their goals. They've certainly done that. In spades. But not without some pain to those developers. With freedom comes the ability to shoot yourself in the foot and enough rope to hang yourself with.

Ember, on the other hand, chose a path of guiding developers to create software easily and safely by providing a broad set of tools, structure and rules to follow. And they have definitely succeeded. But again, not without some pain for the developers. That broad set of tools, the expected structure and all of the rules that go with them must be learned in order to master the framework, and it’s perhaps too much for some to digest.

The Angular and Ember communities are the ones pushing the web forward

All of the new features available to us in modern browsers are powerful and amazing, but it’s these two frameworks that truly enable developers to create content that leverages that power in a way that’s pushing the web forward.

It is my hope that there will be increased cooperation between these two core teams, so that they can create something more perfect than they each already have. It certainly seems possible. There are a lot of future developments in this space that both frameworks have overlapping concerns with: Web Components, Shadow DOM, ECMAScript 6 (and beyond), even the future of HTML standards.

More importantly, I hope to see more interaction between the Angular and Ember communities (meaning you, dear reader) in general. Sharing techniques and strategies across frameworks only serves to give everyone a better understanding of web development and help these two frameworks evolve.

Maybe one day they will be one framework… Maybe one day we’ll all be Embular developers.

Links to the rest of this series:

Part 1 - Comparing Ember and Angular
Part 2 - What's Great About Angular
Part 3 - What's Great About Ember
Part 4 - What Angular Could Learn From Ember
Part 5 - What Ember Could Learn From Angular
Part 6 - Two Paths Up The Same Mountain

Embular Part 5 - How Ember Should Be More Like Angular

Constructor-based dependency injection as an obvious feature. Angular forces a constructor-based DI style that uses constructor functions with parameters. The style is carried throughout the framework and is plainly obvious to any developer that is writing code against Angular. In essence, it forces dependency injection. As an added bonus, this style of dependency declaration and injection enables Angular to detect circular dependencies at run-time.

Ember on the other hand, does not have this exact same mechanism. While you can inject your dependencies at time of creation with Ember via EmberObject.create({ deps: here }), the actual injection of those dependencies is optional. Meaning if one of those dependencies doesn't exist, it will still create the object. There also currently isn't a mechanism for circular dependency checking. The final issue related to how Ember handles the injection of dependencies is that it's not really apparent to the developer where dependencies are being "injection". The short answer: Anywhere you see this.get('something") is an entry point for a dependency. So there are multiple points where dependencies can be injected into your classes, whereas in Angular, there's one obvious point they are injected from, and it helps guide the developer towards dealing with dependencies in that manner.

Angular has a cleaner, neater API. Angular’s api revolves around a small set of primitives: controllers, service providers, directives, and filters. Along with a uniform DI syntax, these primitives allow Angular to be learned quickly and easily by new developers. Angular gives you a powerful set of tools, and then gets out of your way.

In contrast, Ember’s API has a broad surface area. There are many different types of controllers and other Ember primitives and it’s really hard to tell what you should and shouldn’t worry about using when you’re first starting out.  Combine this with an API that isn’t always easy to read and it can be difficult for a developer new to Ember to figure out what’s really happening. For example: App.FooController = Ember.Controller.extend({ foo: 'bar' }) to create a controller, while fairly terse, doesn't make any sense to someone from outside Ember. It reads like "set App.FooController  equal to Ember.Controller, and extend Ember.Controller with this object literal I'm giving you were foo is set to 'bar'".... When I first saw this format I was thinking, "What am I extending? Is this like $.extend? If so, why am I extending this Controller object over and over again?" By that token, angular.controller('FooCtrl', function($scope) { $ = 'bar'; });  just reads more fluently. "Angular, create a controller, named FooCtrl, it needs $scope, and it should put 'bar' on foo on scope".

Even computed properties, one of Ember's better features, don't read easy on the eyes to new developers. excitedFoo: function() { return this.get('foo') + '!!!'; }.property('foo')  ... Anyone new is going to be like "What the hell is this property method on this anonymous function? Where did that come from? How do I call this new function?"

Handlebars is ugly. There I said it. It's ugly. <div {{bind-attr thing="this" blah="that"}}></div> Is just plain ugly compared to dealing with Angular's templating... which is just plain HTML.  That said, however, HTMLBars is coming, and it will completely change all of that and *should* level that part of the playing field.

Angular can stand alone. Angular doesn't require any additional libraries to to function. Ember on the other hand, requires JQuery and Handlebars to function. Which only adds to Ember's already fairly immense download size. Generally speaking though, this is not a big deal. Once it's downloaded, it's downloaded. But it's worth mentioning because some people do care about this, for whatever reason.

Angular is a lot more lightweight. Let's compare the two current production versions: Angular 1.2.16 (104K min / 37K gzip) vs Ember 1.5.1 (277K min / 75K gzip) is almost half the size gzipped, and almost a third the size if your server admin forgets to enable gzip compression on your web server. And to be clear, that doesn't include the other two files that Ember requires: JQuery 2.0.1 (81K min / 28K gzip) and Handlebars 1.3.0 (43K min / 13K gzip). Those bring the required download to spin up an Ember app to around (401K gzip / 116K gzip) versus (104K / 37K) for Angular. For added fairness we'll include Angular's routing module (4K min / 2K gzip), but that's hardly going to make a difference.  But this probably isn't a big deal. This particular concern is really only a concern the first time a user hits a page, because all of these files should be cached after that. Still, some people look at file size and might not like what they find.

NEXT: Embular Part 6 - Two Paths Up The Same Mountain

Embular Part 4 - How Angular Should Be More Like Ember

Angular has a lot to learn from Ember. I think the ease of use in Angular and it's wide spread popularity may have gotten the idea into the community's head that it's "the best", but that's simply not the case.

Ember's use of convention over configuration. Angular allows developers to follow whatever convention they choose, which sounds like freedom to some, but on a large team it's more chaos than anything. Inconsistent names are a pet peeve at best, and a debugging nightmare at worst. For example a developer could name a controller "FooCtrl", "FooController", or "fooControllerer" or "fooServiceThing"... all legal names, none of them consistent. In fairness, Angular does provide a style guide, but in my experience getting people to follow a convention is a lot easier when a framework enforces and rewards the behavior.

Ember doesn't allow logic in templates. Angular, on the other hand does, via "expressions". These expressions are not quite "Turing-Complete" on their own, but they are very, very close. Expressions in templates are dangerous because they're harder to test. They also move what should have been a concern of your controller into your view. Angular's expression parsing engine is extremely impressive. It really is. Anyone that loves JavaScript should just go look at it, it's lexing pseudo-JS into tokens and parsing into a function that can be called against any JS object, usually scope. The problem with expressions is that they've allowed developers to put way, way too much logic into the templates, which makes that logic harder to test, and impossible to test in isolation. For example ng-bind="someVar + 'some string' + dangerZone('!!!')" or maybe something like: ng-click="foo = 'bar'; blah(foo + bar + '!!!); shazbot = nanoo && nanoo" ... that's totally legal in Angular, and completely insane. Ember does not allow this, you can bind to properties, calculated properties, or in the case of events, actions on the controller; All of which are easily tested in isolation.

Robust routing. As I've stated above, Ember's routing is flat out the best I've seen. The third-party ui-router for Angular comes close, but in the end, it's just a pale replica of what Ember has done, as best I can tell. That's not to belittle ui-router at all, it's a fine piece of code craftsmanship, but Ember has spent more time so far refining routing, and it shows. ngRoute, which is the Angular core offering doesn't even compare, and if it has a "best feature" it's simply that it's not included with Angular by default any longer.

Wire up more for the developer. I realize this might not be a goal the Angular team has, but in the end, Ember has solved the problem of "how can we help the developer" much better when it comes to wiring things up. In the case of routing, as mentioned in my previous article, when you setup a route in Ember and you simply give it a name, it will automatically know where to look for that route’s controller, model and template, as well set up the path it’s looking for.

For example in Ember:{

would be this in Angular:

$routeProvider.when(‘/foobar’, {
   templateUrl: ‘/templates/foobar.html’,
   controller: ‘FoobarController’

That’s not really the end of it though, Ember also has a {{link-to}} helper that allows the developer to create a link to a page, by route name, and also pass a model to that route via the link {{link-to “foobar” shazbot}} will take whatever value (object or otherwise) is in the current controller’s `shazbot` property, as pass it as a parameter to the route, which carries over into the controller as a property.

Ember also has a feature which enables very simple two-way binding to query parameters. Basically, this means when a query parameter such as `#/routePath?foo=bar` becomes `#/routePath?foo=wee` then a property `foo` on the current controller will update from `”bar”` to `”wee”. Likewise, if you update the controller property `foo` to be something else, it will reflect it in the query param in the url bar.

Inheritance and mixins. Ember allows the developer to create a controller, or a component, or a route, or anything really, and then create subclasses of any of those things through basic inheritance. This is a very powerful tool. Combine that with Ember's mixins, and you've got a powerful toolset at your disposal that simply doesn't exist in Angular, at least not without some finagling

Embular Part 3 - What's Great About Ember

Ember also has a long list of what's great about it. It's a list that should be well known, but I feel at times that Ember fans just stink at explaining Ember's merits. Particularly to Angular fans. As I've stated above, my experience with Ember isn't as comprehensive as it is with Angular, but there are a few things about Ember that I absolutely revere and I'm excited to tell anyone who will listen:

Two way binding that doesn't allow you to write untestable code. Yeah, we've got this "two-way binding" thing in every framework these days. But where Ember shines is it forces you to write testable code. By this I mean it doesn't allow for logic in your views the way some other frameworks like Angular do. That means that everything you bind to in your view is exposed as a single, unit-testable property somewhere.

Convention over configuration. Ember uses convention to help the developer organize their code. In Ember 1.5+ this means using ES6 modules so you even know where your files are and what they're named. For example, a route named "test" would automatically look for a "test.js" file under the controllers directory, and a "test.hbs" Handlebars template under the templates directory. Likewise with files for models and the route itself. Convention over configuration means that the one stupid developer, on that other team that you hate dealing with, that always names things in stupid ways, is forced not to be a big, stupid, dumbface.

Adherence to standards. Ember developers have gone to great lengths to try to make sure Ember is moving itself, and your application's codebase towards web standards. For example, custom components are named in a convention that complies with the W3C's web components draft. Having worked with an Ember core team developer, I can tell you that their concern with future-proofing your application by trying to adhere to standards is obvious.

Ember polyfills ES5 (and ES6) functionality where it can. So if you're in a crappy browser, Array.prototype.forEach, map, reduce and filter now all work! This is in contrast to doing things like using angular.forEach, underscore/lo-dash's _.each or JQuery's $.each functions. Frankly, it's just better practice.

Extremely robust routing OOTB. Ember's routing is just flat out better than anything else I've seen out there. Better than Angular's ngRoute, better than Sammy.js, better than ui-router. It's really, really good. I've even heard rumblings that Angular might use Ember's router in the future, but that could just be gossip.

Ember solves problems and wires things up for you. What I mean by this is that in other frameworks, like Angular, you're going to have to wire quite a few things up by hand. In Ember when you add a route named ‘smith’, it’s automatically going to look for a controller either named SmithController or in the appropriate file (if you’re using Ember 1.5’s ES6 modules). This goes the same for a smith template, or a SmithRoute, etc. But none of those things are required, they’re also stubbed in for you automatically. It’s also going to look for a client-side route path “/smith”.

NEXT: Embular Part 4 - How Angular Should Be More Like Ember

Embular Part 2 - What's Great About Angular

Everyone knows that Angular is ridiculously popular. And for the most part the list of it's best features is well known, but for sake of comparison, here's my version of what makes Angular great:

Two-way binding to POJOs. Two-way binding is a must-have these days for JS frameworks. The fact that Angular was the first to market with robust two-way binding to "plain old JavaScript objects" (POJOs), is really what got it going I think.

Constructor-based Dependency Injection. This framework is built around its own IOC container that actually uses a pseudo-constructor-based DI approach that is generally preferred by developers from most contemporary backgrounds (such as Java or C#). This makes Angular highly testable, as well as providing the ability for Angular to easily detect circular dependencies.

Angular helps you organize your code. Angular has the idea of "modules" which help you break your code in reusable libraries. These could be the equivalent of a namespace in .NET or a package in Java. Angular's declaration patterns also help keep code out of global scope, for the most part. It also makes it easy to encapsulate these modules into single files, which would be like "assembly" or "jar" equivalents. This can be a very powerful tool when you're organizing large projects.

Simple bootstrapping. Angular has the simplest bootstrapping process of any modern framework I can think of. Just include one JS file, and add an ng-app directive to the page and you're in business.

Plain HTML for templating. In Angular, you don't have to learn much in the way of custom templating language. The only thing that's different from plain HTML is really the binding shorthand such as {{foo}}, which is generally optional.

You can extend HTML to do what you need it to do. Angular's directives allow you to create your own custom behaviors for any custom (or existing) HTML you choose. This is an incredibly powerful tool. It can be used to create reusable "controls", event bindings, interactions like modal dialogs or slider controls, and even validation.

It's flexible and stays out of the developer's way. Angular hands the developer a set of tools to develop a few primitives like Controllers, Services, Providers, and Views and then gets out of the way. This clears the path for the developer to create whatever he might need to create to get his/her project going, and in whatever way the developer chooses to do so. There are so many ways to skin a cat in Angular that it's pretty easy to discover a path to your goal.

Angular is easy to learn.  Angular's best feature is really a combination of all of the above. Aside from directives, Angular is very easy to learn. Its consistent API, use of plain HTML and plain JavaScript objects are an ingenious approach to a JavaScript application development platform not just because of the wizardry that's gone into developing Angular, but because it's so easy to pick up and use. Having worked in an environment where I had to get a team of 50-60 developers from "zero" to "proficient" in Angular, I can tell you it wasn't hard at all. Most of them just "got it".

It's backed by Google. Everyone knows that, and I think that helps some people "trust" Angular a bit more. Personally, I think this is a silly reason to choose a technology, but, c'est la vie, this is something that some people consider corporate backing when they're choosing a framework. One added benefit to a corporately backed OSS effort is there is a paid, full-time staff working on it.

NEXT: Embular Part 3 - What's Great About Ember

Embular Part 1 - Comparing Ember and Angular

Wee! I can draw things! Yay!
Really I'm probably just high from
marker fumes.
 (photo courtesy: @ebryn)

Stuck In The Middle...

I'm in a sort of unique position to discuss this subject. I have a lot of experience with Angular, and I'm now working at Netflix with an Ember core team member, Erik Bryn.

I have spent the past two years or so developing large single page applications in Angular. I've contributed more than a thousand lines of code to Angular 1.3. I'm a "gold badge" holder for Angular on Stack Overflow. I've spoken at a few events about Angular; Nothing "big time", but apparently I've fooled enough people into thinking I know what I'm doing to be considered an "expert". A lot of that is just the luck of when I got into Angular, and my willingness to share my experience in Angular with others.

My Ember credentials are much lighter (for now). As I stated above, I'm currently working on a team at Netflix alongside Erik Bryn, an Ember core team member. The project I'm working on at Netflix is extremely ambitious, it's a ton of fun to work on, and it's the sort of thing where I'm tossed into the deep end, solving pretty interesting problems in Ember, that are actually a lot more complicated than problems I solved in previous Angular projects.

This was originally going to be just one post, but the size of it was out of control. I'm going to try to bust it into several posts that, hopefully will make it more consumable. As time goes on, I plan to post more in-depth comparisons of individual features in each library as well, which I will also link in this series.

What this series is 

  • It's meant to to be an honest comparison between two frameworks. 
  • A love affair with both frameworks. 
  • A plea to those with bias to toss that bias aside and examine the frameworks more carefully and appreciate them for what they are. Brilliant. 

What this series is NOT

  • This series will not make everyone happy. 
  • This is not a "which should you choose?" examination. 
  • This is not a contest or an attempt to convert anyone from one framework to another. 
  • This is not meant to be an indictment of either one of these frameworks as being flawed. 
  • This is not an attempt to proclaim one of these frameworks to be perfect. 

NEXT: Embular Part 2 - What's Great About Angular