Angular 2.0, what to expect?

Aug, 5, 2015 • Bruno De Simpelaere

Categories: Angular, Html5, JavaScript

Why Angular 2.0 makes sense?

(Edited on 14 september 2015)

Some time ago the Angular team announced they’re building on a version 2.0. This version was going to be revolutionary instead of evolutionary. This may sound drastic, but it’s meant in a good way.

The idea is to keep the good parts of Angular 1.x and make them more compliant with modern web standards. This mainly means using the web components architecture and the renewed ECMAScript 6 standard.

To achieve this, some of the core parts in Angular will disappear, like Two-Way data-binding, $scope and a lot of directives.

I guess this is the reason why a lot of people got cold feet when reading/hearing about the new Angular 2.0.

Alongside these new standards, there’s also a lot of time invested in better tooling to help developers write faster.

No more Mr. ES5 No more mister a-what-now?

ES5 or ECMAScript 5 has been the standard on which javascript is grafted since the “The Renaissance” of Javascript. Together with an obscure “no Flash” policy, this actually has been a real game changer for the language. And Javascript usage began to grown -and still is-.

This Renaissance inspired a lot of enthusiast and professionals to do something with this ugly duckling called Javascript. And frameworks like AngularJS (2009), Backbone (2010) and Ember (2011) sprouted.

Maybe it’s a coincidence that AngularJS was first released in 2009, the year that ES5 has been adopted in browsers. And AngularJS 2.0 will be released around the time that ES6 will be adopted in browsers. I think not…

With this little conspiracy theory, it’s time to tell you AngularJS 2.0 is heavily inspired on the ES6 standard. So prepare to see something magical, classes in Javascript!

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
      console.log(this.name + ' makes a noise.');
  }
}
class Cat extends Animal {
  speak() {
      console.log(this.name + ' miauws.');
   }
}
var mittens = new Cat('Mittens')

Codesnippet Example of an ES6 class

ES6 is more than classes, it has a better way of scoping variables, Arrowed functions and modules. If you’re wondering what ES6 can do for you, take a look at ES6-features.

Web components you say?

Angular 2 plays nicely with web components built using other libraries (Polymer, X-Tag, and others), allowing you to pass data into them as easily as if they were written in Angular. Angular components use web standards (such as shadow DOM and the HTML5 template tag) in browsers that support them.

angular.io

Web Components isn’t a thing invented by Angular (or maybe partly) but is a new standard in the HTML landscape. Web components are meant to create reusable snippets of markup and styles. The markup and styles would be bundled in a custom tag.

<video>
  <source src="movie.mp4" type="video/mp4">
  <source src="movie.webm" type="video/webm">
  <source src="movie.ogv" type="video/ogg">
</video>

Codesnippet Example of a web component

Sounds familiar? Well actually you could compare them to Angular 1.x directives. The directives introduced in Angular 1.x were also based on the idea of web components. But this was far from implemented in browsers, so they made it themselves.

Now that web components are actually being implemented in web browsers, a lot of the heavy lifting can be done in the browser itself.

In Angular 1.x the directives were interpolated with the initial digest loop, and manipulated the actual DOM. And, as we know, manipulation of the DOM is expensive and can take some time.

Angular 2.0 components use shadow DOM. The shadow DOM is pretty literally a DOM living in the shadow -Sounds evil I know- and isn’t visible in the DOM tree.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Shadow DOM</title>
</head>
<body>
  <div class="date"></div>

  <template id="dateTmpl">
    <style>
      :host,
      :host *{
        padding: 10px;
      }
      :host{
        border: 1px solid #F00;
      }
      .date-wrapper{
        border: 1px solid #0F0;
      }
    </style>
    <div class="date-wrapper">
      <label for="day">Date</label><br />
      <input type="number" id="day" min="1" max="31"/>
      <input type="number" id="month" min="1" max="12"/>
      <input type="number" id="year" />
    </div>
  </template>
  <script>
    // Add the template to the Shadow DOM
    var tmpl = document.querySelector('#dateTmpl');
    var host = document.querySelector('.date');
    var root = host.createShadowRoot();
    root.appendChild(document.importNode(tmpl.content, true));
  </script>
</body>
</html>

Codesnippet A more complete example of a web component

In the example above you can see a more complete example of the shadow DOM, and how it can be used natively in a HTML page.

The first odd duck in the pond would be the <template> tag, like the <script type="text/ng-template"> tag, this <template> tag isn’t loaded until it’s initialized by javascript -thus doesn’t take DOM rendering time-.

Unlike the <script type="text/ng-template">, this will not alter the actual DOM. Thanks to host.createShadowRoot() a paralel universe is created.

Another thing you may have noticed is that we can add styling in the template tag as well. This styling is scoped to the component, except for the :host property this can apply to the element where the template is applied.

Typescript, the billion dollar baby!

Maybe if you’ve been following the Angular 2.0 release track, you’ve heard about AtScript. For those who didn’t AtScript was an extension for TypeScript written by the Angular-team at Google.

This extension made it possible to annotate classes in TypeScript. These annotations were invented to add metadata to a class.

In the example below you’ll see two annotations (prefixed with an @, .. “aaah, AtScript”). The @Componentannotation defines to which DOM-element the class needs to “mount” on. The @View annotation defines which templates needs to be loaded.

// Annotation section
@Component({
  selector: 'my-app'
})
@View({
  template: '<h1>Hello </h1>'
})
// Component controller
class MyAppComponent {
  name: string;

  constructor() {
    this.name = 'Alice';
  }
}

Codesnippet Definition of a component in Angular 2.0, Angular.io

It’s possible to add more options to the annotations, but for the sake of simplicity I’ve only added the basics.

If you’re still with me, you may have noticed I’ve written “was an extension”. This isn’t a typo. Google and Microsoft sat together and merged AtScript and TypeScript into a new billion dollar baby called TypeScript v1.5.

In my humble opinion, this unique collaboration shows AngularJS 2.0 is supported by not only Google but Microsoft as wel. Not a trivial fact, if you’re doubting about the lifespan of this new version.

Migration & Planning

Lucky for us, the Angular-team is not planning to force us to use version 2.0. And will keep updating the 1.x version for while. When version 2.0 will be production ready isn’t very clear but they are working on it.

As far as the insights go, they started a migration of an existing “big app” at google.

They’ve also set up a few migration paths, one of them is called the “big bang” migration path, where you update everything at once. I know… not much of revolutionary idea here. But in some cases this will be the best option.

The other path is to incrementally update your existing application, where you could load new Angular 2.0 modules into an existing application. Or load old Angular 1.x into a new Angular 2.0 application.

Pretty vague isn’t it? Well it seems they’ve already taken some steps in v1.4 to ease the migrating-pain. Like the new Router that is comparable with UI-Router, developed with migration in mind. And will allow the Angular 2 and Angular 1 modules to live next to each other.

Another example would be the improved bindToController property on directives which allows you to bind scope of a directive to a controller. I’m hearing you, this means you can write the logic that’s needed for your directive, outside of the directive.

Allowing to do this, converting your application to classes and annotations will be easier. The logic written outside of the directive translates without much effort to a class. And the properties set on the directive can now be copied into an annotation.

app.controller('userCtrl', function () {
  this.users = [
    {
      firstname: 'Spongebob',
      lastname: 'Squarepants'
    },
    {
      firstname: 'Patrick',
      lastname: 'Star'
    },
    {
      firstname: 'Squidward',
      lastname: 'Tentacles'
    },
    {
      firstname: 'Gary'
    }
  ];
  this.getFirstname = function () {
    return this.users[this.id].firstname;
  };
  this.getLastname = function () {
    return this.users[this.id].lastname;
  };
});

Codesnippet Definition of a controller in Angular 1.3+

app.directive('bsUser', function () {
  return {
    restrict: 'A',
    scope: {},
    controller: 'userCtrl',
    controllerAs: 'user',
    bindToController: {
      id: '@'
    },
    template: '<p>Welcome  </p>',
  };
});

Codesnippet Definition of a directive in Angular 1.3+

If we take the code from above and rewrite it in an Angular 2 way, it would become something like the example below. Please keep in mind the Angular 2 codebase is still in developer preview. This means the following code can be outdated in 5 min, but it’s about how it would work.

    @Component({
      selector: 'user',
      properties: ['id'],
    })

    @View({
      template: '<p></p>'
    })

    class UserComponent {
      id: Number;
      users: Array<Object>;
      getFirstname: Function;
      getLastname: Function;
      constructor() {
        this.users = [
          {
            firstname: 'Spongebob',
            lastname: 'Squarepants'
          },
          {
            firstname: 'Patrick',
            lastname: 'Star'
          },
          {
            firstname: 'Squidward',
            lastname: 'Tentacles'
          },
          {
            firstname: 'Gary'
          }
        ],
        this.getFirstname = function() {
          return this.users[this.id].firstname;
        }
        this.getLastname = function() {
          return this.users[this.id].lastname;
        }
      }
    }

Update

On 26 august, The Angular Team has written a blogpost about the migration from Angular 1 to Angular 2. Read More

Useful links and references

Continue reading

View all articles

Android MVP, Retrofit & Rx

In this article we’ll discuss the benefits of using Rx over Callbacks in (but not limited to) a Model-View-Presenter application architecture. It is assumed you are already familiar with Retrofit and the concepts of Android MVP and RxJava. You can find the example app fro[...]

VRT: The team and development process behind the new 'deredactie.be' app

VRT recently released their brand new ‘deredactie.be’ app. A news application that inherits the style and concept of the existing mobile site and the experience of a mobile app, basically resulting in much faster news-updates and videos. As a member of the native mobile behin[...]