It’s no news anymore that Angular 2.x was written in TypeScript in order to take advantage of language features like types and meta data annotations through decorators. Taking a first look at Angular examples that are written in TypeScript, can feel a bit unfamiliar and unclear to developers that don’t have experience with that language. Even constructs like classes that ECMAScript 2015 brings to the table can be scary enough to keep developers from learning Angular.
That’s why developers with more experience will tell us that we don’t have to write TypeScript or just ES6 if we don’t want to. We can just stick with ES5. Cool, fine. But how do we do that? In one of our last articles we’ve explored the difference between annotations and decorators and to what they translate to in ES5.
In this article, we will use that information, to actually write Angular code in ES5 with the latest version released at the time of writing (2.x).
Want to see things in action first?
Getting started with Angular in ES5
If you’ve read our article on building a zippy component in Angular, you might know that nowadays, there’s quite a bit of work to do, in order to get started if you want to write your application in ES6/TypeScript and take advantage of it’s module system.
The easiest way to get hold of Angular ES5 bundles is npmcdn. Here’s what we need to embed to get started with ES5 and Angular:
@2.0.0-rc.5 is the version number we specify. So that part might change depending on what we want to do.
Now the next question comes up: How can we access and use given annotations and/or decorators? Usually, in ES2015, we would import them from the framework but now there’s no way for us to import them.
Well, it turns out that the bundled version exposes an
ng.core object on the current global scope or reuses an existing one, which has all annotations added to it. In our last article we’ve learned that annotations are just classes, which in the end are just functions. And those functions are called as constructor functions to add meta data to our components. That means, all we have to do is to call those annotation constructors manually and assign them to our component’s
Let’s start off with a simple component that has a template:
That’s it. We have a constructor function that has a component annotation and a view annotation. The TypeScript equivalent would look something like this:
Bootstrapping an Angular app in ES5
When we come to the point that we want to bootstrap our application, we need to define an
NgModule that has everything attached to it that is needed to make our app run, and bootstrap it on a dedicated platform (e.g. browser, webworker or server).
Let’s go ahead and create such a module first.
ng.core.NgModule can be used to create the needed metadata on a constructor function. Just like with our
HelloComponent, we create an
AppModule function like this:
Next, we add
NgModule annotations to it:
Similar to TypeScript world, we have to import the
BrowserModule from the
ng.platformBrowser package, so we can bootstrap our module in the browser environment. Next, we declare all directives and components that are used inside this module, which in our case, is only the
HelloComponent. Last but not least, we tell Angular which component to bootstrap when the module is bootstrapped.
We need to make sure that all of the DOM is loaded before we bootstrap our module. Adding an event listener for the
DOMContentLoaded event and call
bootstrap once triggered, will help here. When the event is fired, we can call
platformBrowserDynamic().bootstrapModule(AppModule) to bootstrap our app:
And of course, the corresponding application template looks like this:
Great we’ve just bootstrapped our Angular application written in ES5! Was it that hard?
Injecting services in ES5
Let’s say we want to add a
GreetingService to our component. The
@Component annotation takes a property
Next we tell our component about it’s injectable types:
This basically tells our component that it should return an instance of
GreetingService when somebody asks for
GreetingService. Nobody asked for it yet, so let’s change that. First we need something we want to inject into our component’s constructor:
To make our component explicitly ask for something that is a
GreetingService, or in other words, to tell the injector that our
greetingService parameter should be an instance of
GreetingService, we need to add a parameter annotation accordingly:
If you wonder why we define a nested array, this is because one constructor parameter can have more than one associated annotation.
Cool, so it turns out that writing Angular code is actually not weird at all. In addition to that, it kind of gets clear that writing Angular code in ES5 requires more typing. But again, in the end it’s up to the application author which language or transpiler to use.
There’s even a better syntax, that makes writing and reading Angular code a breeze.
Check out the demos below!
Get updates on new articles and trainings.
Join over 1400 other developers who get our content first.
Testing Angular Directives with Custom Matchers
Deliver terse, DRY, self-documenting unit tests with Angular using custom Jasmine Matchers and Helper functions.
Testing Services with Http in Angular
Want to learn how to test services in Angular that have an Http dependency? Read more here!
Two-way Data Binding in Angular
Two-way data binding was one of the main selling points of Angular. Since version 2.x, we can build directives that...
Resolving route data in Angular
We often want to make sure that certain data is available before a component is instantiated via routing. In this...
Angular Animations - Foundation Concepts
Animation in Angular is now easy and more intuitive... Learn foundational animation concepts and start animating your Angular components!
Angular 2 is out - Get started here
Yes. The day has come. Angular 2 is finally released and here's how to get started.