Angular 2 in Plain JS

Dave Ceddia bio photo By Dave Ceddia Comment
Updated June 5, 2016 — rc 0
Angular 2 hit Release Candidate 0 in the beginning of May, which brought some changes. The sub-modules of Angular 2 need to be installed manually now, and the bootstrap function is under a different module.

You’ve already invested time – lots of time learning Angular 1. Controllers, services, directives, filters… All those terms finally make sense – it’s been quite a long road to get here.

And now, along comes Angular 2!

And they’re getting rid of controllers? Everything is a component now? What happened?!

“Looking at Angular 2 is like looking at a different programming language.”

Angular 2 looks all-new: new language, new syntax, new concepts. “This is gonna be like learning Angular 1 all over again, but worse!”

This is a fork in the road. A bit like The Matrix.

You can take the blue pill, and stay in Angular-land. Learn all the new changes, the similar-but-different syntax, and why they decided that importing 9 libraries was better than a single script tag.

Or take the red pill, and try out React. It’s a new world with some new concepts, but I think it’s a cleaner and more well-though-out world than Angular 2. After having tried both, I’m sticking with React. If you do decide to go the React route, check out the timeline I recommend for learning it so that you don’t get overwhelemed.

In this post, you will build a “hello world” app in Angular 2, using plain old JavaScript. No ES6, no TypeScript. And it’s gonna take about 5 minutes of your time.

Ready to get started?

Install angular2

This assumes you already have Node.js and NPM. Get those if you don’t!

Open up a Terminal. Create a new directory:

$ mkdir plain-js-ng2
$ cd plain-js-ng2

Create the package.json file with these contents:

{
  "name": "angular2-in-plain-js",
  "version": "0.3.0",
  "license": "ISC",
  "dependencies": {
    "core-js": "^2.4.0",
    "zone.js": "0.6.12",
    "reflect-metadata": "0.1.3",
    "rxjs": "5.0.0-beta.6",

    "@angular/core":  "2.0.0-rc.1",
    "@angular/common":  "2.0.0-rc.1",
    "@angular/compiler":  "2.0.0-rc.1",
    "@angular/platform-browser":  "2.0.0-rc.1",
    "@angular/platform-browser-dynamic":  "2.0.0-rc.1"
  }
}

Install Angular 2 and all its dependencies:

$ npm install
Note: If you have trouble installing angular2, make sure you're using the official NPM registry. Check the one you're using with npm config get registry, and if it's not "https://registry.npmjs.org", run npm config set registry https://registry.npmjs.org.

1. Create app.js

Create a new file called app.js in your favorite text editor. Type this out:

Type it out by hand? Like a savage?
Typing it drills it into your brain much better than simply copying and pasting it. You're forming new neuron pathways. Those pathways are going to understand Angular 2 one day. Help 'em out.
(function() {

  var HelloApp =
    ng.core
    .Component({
      selector: 'hello-app',
      template: '<h1>Hello Angular 2!</h1>'
    })
    .Class({
      constructor: function() {}
    });

  document.addEventListener('DOMContentLoaded', function() {
    ng.platformBrowserDynamic.bootstrap(HelloApp);
  });

})();

2. Create index.html

Create an index.html file and type this in:

<html>
  <head>
    <title>Plain JS Angular 2</title>

    <!-- The stuff Angular 2 needs -->
    <script src="node_modules/core-js/client/shim.min.js"></script>
    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/rxjs/bundles/Rx.umd.js"></script>
    <script src="node_modules/@angular/core/core.umd.js"></script>
    <script src="node_modules/@angular/common/common.umd.js"></script>
    <script src="node_modules/@angular/compiler/compiler.umd.js"></script>
    <script src="node_modules/@angular/platform-browser/platform-browser.umd.js"></script>
    <script src="node_modules/@angular/platform-browser-dynamic/platform-browser-dynamic.umd.js"></script>

    <!-- Our app -->
    <script src="app.js"></script>
  </head>
  <body>
    <hello-app></hello-app>
  </body>
</html>
Type it out by hand? Like a savage?
In an earlier version of this post, I advocated typing this in. Back in those days, it was only 2 script tags, which has ballooned to nine. I will hold no ill feelings if you copy and paste this HTML.

3. Open index.html

Load up index.html however you like. I like running open index.html in a Terminal (on a Mac).

So Easy! Such Angular!

That’s all there is to it. I told you it was easy!

By the way, now would be an excellent time to sign up for future Angular 2 articles! I’ll be going into more detail on Plain-JS Angular 2 as well as TypeScript and ES6, so if you want to stay ahead of the curve, put in your email below!

If you’re curious about those script files being included in index.html, check out my Angular 2 Dependencies Overview.

Let’s look at what’s going on in this little app.

Components over Directives

Angular 2 gets rid of directives in favor of components, but conceptually they’re very similar. Even their code is not that different. Have a look at this diagram:

Angular 2 Component vs Angular 1 Directive

Both specify an HTML tag name (selector vs inferring it from the directive’s name).

Both have associated behavior (Class vs controller).

Both have a template.

Even the chaining syntax isn’t that foreign, coming from Angular 1.

Explicit bootstrap

Angular 2 comes with a function called bootstrap that initializes the app. This bit of code from above starts everything up:

document.addEventListener('DOMContentLoaded', function() {
  ng.platformBrowserDynamic.bootstrap(HelloApp);
});

It listens for a DOMContentLoaded event using plain-old JavaScript, then calls ng.platformBrowserDynamic.bootstrap with the root component.

This is a conceptual shift from Angular 1: Apps are composed of nested components all the way down. Everything is nested inside the root.

Your Turn

Now that you have a (super-basic) Angular 2 app running, you can begin to play around with it. Here are some things to try:

Add a second component

Create a new component that contains your name and render it after the h1 tag.

Some hints:

  • Every component needs to be explicitly required in order to use it. The property belongs inside Component and is called directives (oddly enough). It contains an array of components (which are just Javascript objects). e.g. directives: [MyName] would require the MyName component and let you use its tag.

  • Templates don’t appear to be limited to a single root node like with Angular 1 directives.

Add a list of names

Add a ul tag with a nested li for each name.

  • You’ll need the new ngFor syntax. It replaces ng-repeat, and the attribute looks like *ngFor="let name of names" (there’s a * in front, it’s important).

  • Variables declared on the constructor’s this object will be available from within the template using ngFor and the familiar {{ curly_braces }} syntax.

Give Up?

Try to figure out the exercises on your own first. Refer to this example from the official Angular 2 docs - their syntax doesn’t look the same, but I bet you can work it out.

But if you’re truly stuck, the answers are below (hidden). Click to reveal.

[answer] Show your name
var MyName = ng.core
  .Component({
    selector: 'my-name',
    template: '<span>Dave</span>'
  })
  .Class({
    constructor: function() {}
  });

var HelloApp =
  ng.core.Component({
    selector: 'hello-app',
    template: '<h1>Hello Angular 2!</h1><my-name></my-name>',
    directives: [MyName]
  })
  .Class({
    constructor: function() {}
  });
[answer] List of friends
var FriendsList = ng.core
  .Component({
    selector: 'friends',
    template: '<ul><li *ngFor="let friend of friends">{{ friend }}</li></ul>',
    directives: [ng.common.NgFor]
  })
  .Class({
    constructor: function() {
      this.friends = ["Alice", "Bob", "James", "Aaron"];
    }
  });

var HelloApp =
  ng.core.Component({
    selector: 'hello-app',
    template: '<h1>Hello Angular 2!</h1><friends></friends>',
    directives: [FriendsList]
  })
  .Class({
    constructor: function() {}
  });

Choosing a framework is difficult.

Learning React? Sign up and get my React Learning Timeline PDF, and also weekly-ish articles about React, Angular, and JavaScript.

A few emails per month — unsubscribe any time.
comments powered by Disqus