Writing An Angular2 Component in Today`s JavaScript (ES5) – Beta Edition

With a lot of changes happening since Alpha 48 all the way to Alpha 55 (later labeled as Beta 0 as well), the way you write components in general, even in plain JavaScript has changed from what might have seen in other posts.

Then the beta was out. Learn about it here:

For a hello-world app at least, things didn’t change in beta than in Alpha 55, here’s how to do it.

Loading Angular 2

Here are all the files we’ll need:

If you played with Angular 2 alphas and JavaScript before, you’d have seen some Angular.sfx.*.js files. sfx used to refer to “self extractable”, meaning you don’t need a package manager to use it. It got renamed to umd, which I assume is like “Universal Module Dependency”.

Also, some parts were extracted from the core, like zone.js, the, the magic that saves you from things like scope digest cycle in Angular 1, into an angular2-polyfills.js file.

Finally, Reactive Extensions, a library that Angular 2 uses to replace promises and more, was extracted from Angular main bundle as well, while still copied to the CDN, as Rx.umd.js.

So, the steps to get what files to load:

I’m assuming if you are using ES5, you don’t want to even bother with NPM. So, I set the steps based on that.

  1. Go to AngularJS CDN https://code.angularjs.org
  2. Search for 2.0.0 and find the highest version folder. For example 2.0.0-beta.0.
  3. Look for the following files in the folder, and use them in order:
    1. Rx.umd.js
    2. angular2-polyfills.js
    3. angular2-all.umd.dev.js

This will give you the ng global variable, which is what we will you to define and bootstrap our components.

You will later want to include things like the “http” file and “router” file to use their corresponding functionalities.

Defining A Component

There are two ways we can use to define components in JavaScript:

Static Property

This should be familiar to you if you ever tried to write object oriented code in ES5:

  • You define poor-man’s class, ES5 style, as a function (the convention is to use PascalCasing for these).
  • You set a field called annotations on the function itself to be like a static class property. It’s the equivalent of attributes/annotations used in TypeScript.
  • You add the ng.core.Component annotation.
    That’s where you include the selector, template and other component properties just like in TypeScript. Except in ES5 you don’t have multi-line strings.

    • Note the PascalCasing. It’s another class.
    • The selector is almost always an element CSS selector. A custom element typically is lowercased with at least one hyphen - in it, like hello-world, which maps to <hello-world> in our HTML.
    • The template is just like the template in an Angular 1 directive (except with Angular 2 template syntax). You can also use templateUrl.
  • A couple of gotchas:
    • Note the part ng.core.Component. This is due to Angular splitting it’s code into different parts like “core”, “common”, “compiler”, “platform”, etc.
    • If you miss the new in there, it won’t work, and you will be scratching your head for quite a bit.

Fluent API

This tries to get even closer to TypeScript. It’ll either make you feel you have TypeScript already, or make you die to move to it!

  • Notice the same ng.core.Component explained above
    • Gotcha: This time do NOT use new before it. Actually it will NOT work if you add new. Beware of this gotcha.
  • After that, you use Angular’s own Class class (pun intended).
    • The “constructor” field maps to the function in the first example.
    • Gotcha: You MUST add a constructor even if it’s just an empty function, or else it will not work.

Data Binding

This is worth its own article. For simplicity, let’s look at a simple ng-model example:

  • We used the two-way data binding syntax [(property)]=value.
    • the syntax [attribute]=”value” is used to bind from JS objects to DOM attributes and other directive attributes.
    • The syntax (eventName)=”handler” is used to bind from the DOM (like DOM events), to a JS function that handles the change/event.
    • As [] means JS => DOM, () means DOM => JS. [()] is used for 2-way data binding.
  • We said ngModel, not ng-model. This is a relatively recent and controversial Angular 2 change, that all component DOM attributes (Angular components or custom components), will use the camelCasing, instead of hyphen-separated (also known as kebab-casing).
  • In earlier Alphas, you needed to set a directives property to your component to use ngModel, ngFor, ngIf, etc. These are no longer required.
    (If you don’t know what that is, it’s dead anyway. Don’t bother for now)

Bootstrapping The Component

OK, let’s say we wrote the above components, and we want to use them. How would we do that?

The convention in Angular 2 is to have an application component. Something like:

  • Note that for us to include other custom components in our template, we had to add them to another property, called “directives”.
    We didn’t have to do this for the built-in things like ngModel.

Then in HTMl, we use the app component:

  • It’s another Angular convention to put the default UI (like a loading indicator) inside the app component.
    Angular 2 will replace that with your template when it loads it.

Now, to make the magic happen, you need:

  • If you don’t know DOMContentLoaded event, you probably were doing a lot of jQuery. This is the standard equivalent of the jQuery “ready” custom event.
  • If you did this in previous alphas, you might notice that part ng.platform.browser.bootstrap.
    • I mentioned earlier that Angular2 functionality has been split into different parts. plaftorm is one of them (this is like a namespace in C#/Java – the convention for namespace casing is camelCasing).
    • Since you can use AngularJS with even something that is not HTML at all (like NativeScript for native mobile UI), that’s why (I guess) we need to select the “browser” platform to bootstrap it.

And that’s it. You get a nice application running!

Full Example

Here’s a complete application for easier read:

Share With Friends:

P.S. Please help me out by checking this offer, then look below for a small Thank You.

How did I learn that?

As a bonus for coming here, I'm giving away a free newsletter for web developers that you can sign up for from here.
It's not an anything-and-everything link list. It's thoughtfully collected picks of articles and tools, that focus on Angular 2, ASP.NET 5, and other fullstack developer goodies.

  • dka

    “You will later want to include things like the “http” file and “router” file to use their corresponding functionalities.”

    I included https://code.angularjs.org/2.0.0-beta.0/router.js and get the following console error:
    SCRIPT5009: ‘System’ is undefined
    router.js (2,1)
    Any ideas? I’m just getting started here so sorry if it is something simple :)
    Looking to do ES5 only.. no TypeScript for now.

  • stigok

    Thanks for the post!

  • Nicholas Johnson

    Good to see some decent ES5 content coming on. TypeScript is cool, but it hides the internals. We need to understand what is actually happening at a nuts and bolts level, then we can lay TypeScript on top.

  • dhruv

    i want syntax about angular 2 with
    webapi using javascript

  • Osama bin Login

    A couple of glitches with this example.

    1 – “Flent” should probably be “Fluent”

    2 – the .html file doesn’t include the .js file. I stuck in after the other script tags.

    3 – it crashes on more recent versions. Your example uses beta-0, which works perfectly. But beta-1 through -9 crash with a stack overflow, after printing “Hello Angular2!” a zillion times. the ‘snapshot’ version and ‘2.0.0-snapshot’ both complain that ng is not defined…. even though they’re just a few days old.

    I know it’s a hassle publishing stuff; you have to keep fixing glitches, that seemed to not exist before.