AngularJS and ES6

I was working on refactoring some of my Javascript code for an Angular app when I decided that I would convert most of my client side code to ES6 so that I am ahead of the curve come AngularJS 2.0. I have begun taking baby steps in this direction but information is hard to come by at the moment on using ES6 with AngularJS. I ran into a major hurdle before I could get my rudimentary HelloWorld app running and that is what instigated me to write this post (finally a post after 3 years). Hopefully it will help someone out.

The interwebs tell me that recommended way to get up and running with ES6 is to use Traceur. The GitHub page has a handy Getting Started guide but if you are interested in learning more about ES6 I would highly recommend watching this fantastic little course on Pluralsight called Javascript Fundamentals – ES6 by Scott Allen and Joe Eames.

Without going into too many details – Traceur lets you transpile your ES6 code into ES5 so it can be used in the current browsers. You can traspile either on the fly by directly referencing the following traceur libraries in your web page and setting some flags:

<script src="https://google.github.io/traceur-compiler/bin/traceur.js" data-require="traceur@*" data-semver="0.0.0-20140302"></script>
<script src="https://google.github.io/traceur-compiler/src/bootstrap.js" data-require="traceur@*" data-semver="0.0.0-20140302"></script>
<script>
      traceur.options.experimental = true;
</script>

or by transpiling the files offline using the traceur command line tool and then referencing the transpiled files in your HTML:

traceur --out app.js --script app.es6.js

After all the reading and watching, I thought i’ll write a plunk real quick to test this out. I decided I’ll create a class for my controller:

//MainCtrl.js
export class MainCtrl {
    get name() {
        return "World!!!";
    }
}

Import it where I am setting up the Angular module and create the new controller from my imported class

//app.js
import {MainCtrl} from "MainCtrl";

var app = angular.module('plunker', [])
.controller('MainCtrl', MyClass);

Bootstrap Angular:

<html ng-app="plunker">
</html>

Add a reference to my module in a script block:

<script src="app.js" type="module"></script>

That’s it (or at least that is what I thought), hit Run and …

Error: [$injector:nomod] Module 'plunker' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument. 

Plunker

I wrote the same code locally on my machine, transpiled it offline, concat-ed them and reference a single file in my html and everything worked. However, I was just not able to do the same on the fly. It turns out I needed to jump through some hoops before I could get it working. It turns out that the

<script type="module"></script>

polyfill runs asynchronously so initializing Angular can be a little tricky.

The good fellows watching the Traceur Github issues helped me quickly figure out what was going on. I had to block the initialization of Angular until after the module evaluation and would have to bootstrap Angular manually, like so:

<script>
      System.import("app").then(function(a){
        angular.element(document).ready(function() {
          angular.bootstrap(document, ['plunker']);
        });
      });

</script>

Plunker

That’s it. I had my Hello World app built on top of ES6 running.

Now that I have Angular bootstrapped and running, I intend to explore how to go about taking the most advantage of ES6.

Advertisements

2 thoughts on “AngularJS and ES6

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