What I Learned at ng-conf: Write AngularJS with Migration in Mind

I recently attended ng-conf 2015, the second annual conference for all things AngularJS, in Salt Lake City. One theme prevalent throughout almost every presentation was the ongoing efforts to build Angular 2.0, and the major changes it will bring to the framework. With the first release of Angular 1.4 now available, this is a perfect time to think about migration. Doing this now will make your life easier once Angular 2.0 is released. Below are several ways you can write code in Angular 1.x today in a way that will be easier to migrate in the future.

Angular 1.4 (and the new router)

Now that Angular 1.4 has been released, consider updating to this latest version. Aside from keeping you up-to-date and diminishing the number of breaking changes you might have to fix, this will also allow you to use the new router.

The new router is comparable in features to UI-Router, and is a significant improvement over the old ngRouter. The major difference is that the new router was built with migration in mind. It will allow Angular 1.x modules and components to live alongside Angular 2 modules and components. You’ll be able to update your code incrementally, rather than changing your entire app all at once. If you do nothing else to prepare for Angular 2.0 migration, you should at least switch over to the new router.

ES6

One way to prepare for moving to Angular 2.0 is to write your current 1.x code in ES6. ECMAScript 6, as it is more formally known, includes numerous new features like modules, classes, arrow functions, new utility methods and more. You can take advantage of these features now, and use a transpiler (like Traceur or TypeScript 1.5) to compile ES6 code to ES5, to ensure compatibility with all browsers.

In their talk at ng-conf, “Angular 1 meets Angular 2,” Michał Gołębiowski and Andrew Joslin explained how to write services and directives using ES6 features.

Services

You can write services with the future in mind simply by creating an ES6 class to define the service, rather than a function.

For example, instead of:

You can instead write your service as a class, like so:

In this example, I’m using $q as a constructor, rather than creating a deferred object to hold the promise. Angular 1.3 has incorporated some of the ES6 promise constructor API, in particular the ability to do without a deferred object when resolving or rejecting a promise. As promises are a massive topic in and of themselves, I’ll just say that there is a lot more information on the topic that you should definitely check out.

You may notice the ‘=>’ symbol in the above example as well; this arrow function, represented by the “fat arrow” as it’s lovingly called, is a new shorthand function syntax that will actually share the scope of its surrounding code; in other words, you can access a this reference from the immediately surrounding code. That way you don’t have to deal with specifying an additional self variable just to access it within the promise’s resolve function.

Directives

You can also write directives in a more future-minded way. First, you can remove almost all references to$scope. As of Angular 2, $scope will no longer exist, and the this keyword will be used instead. You can make that change now using the controllerAs syntax (and usingbindToController: {} rather than scope: {} for directives.

Instead of a directive like this, written in ES5:

The code can be rewritten like so:

In this example, I specified the controller for my directive, but then specified controllerAs; this will be the variable used to access the controller’s methods and variables from the template. And instead of referring to $scope in the controller, you can now use this.

Now, rather than adding variables to a$scope, you can specify them in a bindToController object, which makes all its properties and methods accessible in the controller and the template. You do still need to declare an empty scope, since the directive requires it, but this can easily be removed in Angular 2.

Best Practices

Finally, it’s worth mentioning that following best practices will always make your life easier, whether or not you’re preparing for a code migration. I won’t list all the best practices I can think of here, because (1) there’s no way I’ll list everything, and (2) John Papa does a much better job of it in his Angular Style Guide, as well as his talk at ng-conf last month. What I will say is that it is crucial to make sure your code is readable, understandable and organized. Something many developers can forget is that a large part of our job is about communication. If you can’t write code that is easy to locate, easy to read, DRY and encapsulated, it will be that much harder for you and future developers to maintain and improve your codebase.

Updating Angular and migrating to 2.0 is not going to be a painless task, but there are ways you can significantly decrease the time and effort required to do so. Incorporating ES6 features now, updating angular to the latest version, eliminating scope where you can and following best practices are all steps that you can take incrementally, when and where you can, to make your life tremendously easier in the future.

This article was originally published on EffectiveUI’s blog on April 20, 2015.