Angular 2+ - A Getting Started Guide for Beginners
Since about half a year, I’m organizing a local Meetup group around Software Craftsmanship. I recently also published a video course on “Learning Angular 2 directives” and given Angular 2 finally released RC1, I decided to organize a Meetup session to introduce Angular 2 to our members. Hint: check out the screencast at the end 😉
Contents are based on Angular version >= 2
Wohooo! This article earned some fame and was chosen at rank #1 out of ~1500 Angular 2 articles published in May-June 2016. Read the whole story 😊
Intro
This article is for those of you that are new to Angular 2 or even to web development in general. Here, I’m going to give you a good overview what Angular 2 is all about, highlighting some of the main concepts behind. The idea is to give you a good starting point from where to go and do further research.
TL;DR - Check out the video screencast at the end of this article 😉
If you did already some coding examples in Angular 2, then I’m probably going to bore you :smiley:. But maybe you want to dive deeper with my Learning Angular components video course I recently published 😉.
Learn how to build efficient Angular 2 directives with this fast and interactive video course
Big Picture
Here’s a simple classification of today’s web application architectures.
Server-side rendered
In server-side rendered applications, most of the application’s logic resides on the server, and remains there. The user basically enters the URL, the request gets send to the server, which then produces the final HTML containing the requested data and sends that back to the browser which simply renders it out. When the user interacts with the page, that request gets again sent to the server, which in turn generates a new HTML page and serves it back to the browser.
This is how the web has been designed, a perfectly valid model and what many pages still use today.
Client-side rendered
Modern web pages often require to work more like applications do on the desktop, though. People demand for a much better user experience, more interactivity, fast transitions between “pages” and even offline capabilities. That’s where the so-called SPAs (Single Page Applications) come into play.
When the user enters the URL, the web server responds with an HTML page, but also with a set of resources (JavaScript files and images) that make up our client-side application. The browser receives that, loads the JavaScript application and “boots it”. Now it’s the job of that application to dynamically generate the user interface (HTML) based on the data, right from within the browser. After that happens, every new user action doesn’t reload the entire web site again, but rather the data for that specific user interaction is send to the server (usually by using the JSON format) and the server in turn responds with the just the amount of data requested by the JavaScript client, again using JSON (normally). The JavaScript application gets the data, parses it and dynamically generates HTML code which is shown to the user.
As you can see, the amount of data that is being exchanged is very optimized. However, a big downside of such type of applications is that the startup time is usually much longer. You might already have figured why: well, because the browser doesn’t get the HTML code to show, but rather a bunch of JavaScript files that need to be interpreted, and executed, and which in turn then generates the final HTML to be shown to the user.
Server-side pre-rendering, isomorphic JavaScript or universal JavaScript
Just some names that are currently being used for the third type of web application I’d like to show you. As you might guess, it aims at taking the best of the server-side rendered web apps and SPAs.
In a nutshell, what it does is the following. When the user enters the URL, the server loads the JavaScript application on the server side, boots it up and then delivers the already (by the JavaScript app) pre-rendered HTML plus the JavaScript app itself back to the client. There, the browser interprets the JS app and runs it, which has then to be intelligent enough to resume where the server has left off.
The advantage is obvious: you get fast startup times, but still the benefit of a SPA as mentioned before.
Why Angular 2? What’s different?
Ok, let’s get to the meat. Why should you be interested in Angular 2? Here are a couple of things I picked up mainly from Brad Green’s and other core member’s talks from a couple of the latest conferences.
Angular 2 is a platform!
At his keynote at NgConf 2016, Brad Green named Angular 2 a platform rather than a library or framework. The main reason is that it is split up into modular pieces, build upon each other, some of which can even be used outside the Angular ecosystem.
There are some building blocks, like the dependency injection, decorator support, zone.js (which btw. can be used completely independently from Angular and is currently under discussion at stage 0 at TC39 for being included into the ECMA standard), a compilation service, change detection and a rendering engine (which is platform independent). On top of that, there are other libraries such as Angular Material (an UI library with material design support), mobile and Universal etc.
There are even modules such as i18n, the router and animation that can be used from within Angular 1.x as well.
Extremely fast!
Angular 2 is designed to be extremely fast. Well, every new JS library would probably claim that, but there are some differences in the approach Angular 2 is taking.
First of all, they’re currently hardly working on a so-called “template compiler” or “offline compiler” the so-called Ahead-of-time (AoT) compilation. Many JavaScript frontend frameworks basically render the templates dynamically into the browser’s DOM at runtime, which requires a templating engine of some kind. Angular 2 templates and it’s components are made in a way that Angular 2 is able “to reason about your app’s templates” and thus to generate an AST and consequently to translate all of your templates into pure JavaScript code at compile time. This is huge IMHO 👍.
As a result, your deployed app doesn’t require any templating engine to run, but it rather contains highly optimized JavaScript code for directly manipulating the DOM. That’s super fast and moreover the resulting Angular 2 library gets a lot smaller, as you don’t need its templating engine any more when you deploy in production.
And that leads us to the next part.
Small!
The library gets really, really small.
@John_Papa @arhoads76 @DanWahlin I believe current numbers are something like 49K via Rollup and 25K via jscompiler.
— Brad Green (@bradlygreen) May 31, 2016
By being able to strip out useless parts with the template/offline compiler, lots of stuff can already be dropped when deploying in production. Furthermore, the goal is to use a bundler that supports tree shaking and thus reduce the size of the final compiled JS files even more by eliminating everything that is not actively being used within your application. Frankly, if you don’t use the routing module of angular, it simply won’t get included in your final app.
Tree shaking is basically “dead code elimination”. By analyzing which JavaScript modules are used and which aren’t, compilers that support such approach can eliminate the unused parts and thus produce a much more optimized and smaller bundle. Obviously a proper module system such as ES2015 modules has to be used for this to work.
Lazy loading, built-in
Finally! Lazy loading has been a hot topic already for Angular 1.x and many other frameworks. When you build a serious application, it might get quite big pretty quick. That said, you cannot force your users to download megabytes over megabytes just to get your app boot up, especially on flaky Internet connections or mobiles. That’s why lazy loading needs to be implemented. The idea is to load only those parts the users most heavily use and load other parts on demand when needed. This was particularly hard in Angular 1. ocLazyLoad being one possibility to achieve this.
Now with Angular 2 this is finally built-in right from the beginning, through the framework’s router and so-called “lazy routes”.
At the moment of writing this article, the router has been rewritten and thus there are no docs at the moment. It should be available shortly. Till then, you may want to give this video a go, where Misko Hevery explains it.
Angular Universal
This is Angular 2’s answer to isomorphic JavaScript or server side pre-rendering. Again, it’s all about performance, to get the app to the user as quickly as possible.
angular-universal is a library that lives under the Angular 2 GitHub repository with the goal of making server-side rendering as easy and straightforward as possible. Since Angular 2 is made to be platform agnostic, it can be executed in non-browser environments without too much issues.
So, when loading a universal Angular 2 app, from a high-level perspective, what happens is the following:
- Your user opens your universal Angular app, also maybe invoking a client-side route like
http://myuniversal-app.io/people/detail/1
- Some angular-universal compatible server gets the request, knows it is a client-side route and thus boots the Angular 2 root component (usually
app.component.ts
) on the server side and executes it. - The server then delivers the already rendered application state of that invoked client route inside the
index.html
back to the browser - The browser renders the HTML, thus the user will see the person with id 1 rendered immediately (as it is already present in the HTML)
- Meanwhile the Angular 2 app again boots,but this time on the client-side (the browser) in the background (in a hidden div basically). A library,
preboot.js
, records all user events like clicks, input changes etc. until Angular 2 is fully loaded. - When the Angular 2 app is ready, it will have the same rendered state as the server has delivered previously.
preboot
then replays all of the user events against that client-side rendered app. - Finally, the client-side rendered app gets activated and the server-rendered HTML is being dropped
That was really from a birds-eye perspective but you get the idea. To know more details, a good place to start is the quickstart guide. Also the universal-starter repository has some good examples to play around with.
Currently the angular-universal supported server frameworks are Node and ASP.net. But there’s currently support for Java, Go and PHP in the works.
Unified Development
Something I’m particularly excited about is the approach of having a unified development model.
Angular :heart: Mobile
You can choose among 4 different possibilities for developing mobile applications with Angular 2.
Angular Mobile Toolkit - focuses mostly on a new architectural approach to creating web applications: Progressive Web Apps (PWA). These are normal web applications, that facilitate modern web technologies like service workers for offline caching and a special (non-standard right now) manifest file that instructs Chrome to provide “installation like capabilities” for the app, s.t. it can be added onto your homescreen. Google I/O 2016 was all about PWA development. Just check out some of the talks on Youtube. Also, JavaScriptAir’s latest talk on it might be relevant.
Ionic 2 - is a hybrid mobile application framework. That simply means you build a web application and package it in a native installable package for iOS and Android that can be installed through the corresponding app stores. The app itself is served through a WebView component, which means you’re running a web application in the end. Access to underlying APIs is achieved through Apache Cordova. Ionic specializes in providing you the tools for setup and building the native app packages. Moreover it gives you a highly tuned UI framework and mobile routing support. They recently also announced futures support for PWAs, so it’ll be quite interesting to see it evolve.
NativeScript - is a framework developed by Telerik. Different to Ionic, it “compiles” to a native application. Actually your JavaScript code is being executed through a special JavaScript VM (like Chrome’s V8) which builds the bridge to the underlying native platform. But anyway, take a look at this video with John Papa, Burke Holland and TJ VanToll showing off some NativeScript capabilities.
React Native - There’s the possibility to even use React-Native with Angular 2. Unfortunately I’ve not done anything with it yet, so you may want to browse the web for it if you’re particularly interested in this one 😉.
The trick is just to get the right one for your needs 😉
Installed Desktop
When talking about “installed desktop” we don’t mean like running an Angular 2 app on a desktop browser, but rather to run it inside an installable application. This is powered by Electron and Windows Universal (UWP). Watch what Brad Green had to say about it at NGConf 2016 :video_camera:.
A very important point here that’s easy to miss: by running Angular 2 directly from within a Web Worker, not only you get an enormous performance boost as it runs in a separate thread, but you also get access to the underlying platform, Databases etc..
The Web Workers specification defines an API for spawning background scripts in your web application. Web Workers allow you to do things like fire up long-running scripts to handle computationally intensive tasks, but without blocking the UI or other scripts to handle user interactions.
Not convinced? Well, most probably you’re already using an Electron app, like VSCode, or Slack or some of these:
The 7 Key Concepts behind Angular 2
At NGConf 2016, John Papa had a slide in his talk describing the seven main key concepts behind Angular 2. These really nail it.
Modules and the ES2015 story
Ok, at this point I should probably stop and we should take a broader look at what modules are all about.
Initially in web development, you most likely did something like this:
<html>
<head>...</head>
<body>
<script src="./vendor/jquery.min.js"></script>
<script src="./vendor/super-awesome-datepicker.min.js"></script>
<script src="./myapp.js"></script>
</body>
</html>
You simply include the required JavaScript files in the correct order. Within your myapp.js
you might have..
function initDatePicker(someDateValue) {
$('#myBirthDateInput').superAwesomeDatePicker({
value: moment(someDateValue)
});
}
A couple of things to note here. We rely on global state and libraries to be loaded. Like $
for jQuery and moment
and superAwesomeDatePicker
. These libraries need to be present at the moment this function is executed. Meaning you have to load all of the scripts in the right order, based on their respective dependencies. This is simply not feasible for large scale applications with hundreds of different JavaScript files. That’s why module systems have been created, like the AMD standard implemented by - for example - RequireJS:
define(['jquery', 'moment'], function($, moment) {
function initDatePicker(someDateValue) {
$('#myBirthDateInput').superAwesomeDatePicker({
value: moment(someDateValue);
});
}
return initDatePicker;
});
Note, we now have imports, like a dependency called jquery
and moment
get defined somewhere and imported as $
and moment
inside this specific file. In turn, also functionality within this file gets exported with return initDatePicker
s.t. it can be imported by other files in the exact same way. And so on.
This worked, but wasn’t always ideal. Or better, there have been different other patterns around, and they weren’t always that nicely compatible and interchangeable. With ES6 or ES2015, the TC39 (the committee deciding over the next ECMAScript features to be implemented by browsers) finally specified a standard syntax for defining JavaScript modules.
import * as $ from 'jquery';
import * as moment from 'moment/moment';
function initDatePicker(someDateValue) {
$('#myBirthDateInput').superAwesomeDatePicker({
value: moment(someDateValue)
});
}
export initDatePicker;
A much more clear and expressive syntax.
Another notable feature that many developers coming from languages like Java or C# may like, are classes and inheritance:
class MyApp {
_someDateValue;
constructor(someDateValue) {
this._someDateValue = someDateValue;
}
get someDateValue() {
return this._someDateValue;
}
set someDateValue(value) {
this._someDatevalue = value;
}
static someStaticFunction() { ... }
}
Finally, another construct we need to learn about to understand Angular 2 apps are decorators.
@DebugLog({
...
})
export class MyApp { ... }
These simply provide metadata to the underlying framework, in this case Angular, about the class. There is currently a proposal for decorator support in ECMAScript. Also, other than many might think, in JavaScript, decorators are not annotations.
Annotations and decorators are two competing and incompatible ways to compile the @ symbols that we often see attached to Angular components. Annotations create an “annotations” array. Decorators are functions that receive the decorated object and can make any changes to it they like.
Traceur gives us annotations. TypeScript gives us decorators. Angular 2 supports both. nicholasjohnsom.com
Also, check out the article on Thoughtram on this topic.
So, can I use all of this in the browser right now? No, unfortunately not. What you need is a compiler or transpiler. Currently Babel and TypeScript are the most popular ones.
The Angular team decided to go with TypeScript and has written its entire codebase with it. TypeScript has been created by Microsoft already in 2010 and then went first public in 2012. It really kicked off only recently, though, with Angular 2. The main difference to other transpilers is that it adds optional type support to JavaScript. First of all, this allows to discover and prevent nasty errors at compile time and second it opens up numerous possibilities for better tooling support.
Ok ok wait wait, so how is this relevant for Angular 2? Angular 2 is written entirely in TypeScript and while it’s not impossible to write Angular 2 applications in ES5, it is highly recommended to write them in ES6 or TypeScript to get the best out of it. This way you can start using all of the above mentioned features on modules, classes, decorators and much more we didn’t even cover.
Long story short, you should get accustomed to the new features of ES2015. Browse the web or check out my article which gives you a quick intro and links to many other useful resources.
ES6: Get introduced to the next generation JavaScript
Web Components
Component based architectures is the new paradigm for frontend development. This is not something particular to Angular but is something that’s shared among other libraries like React, Ember or Polymer as well. The idea is to build autonomous pieces with clearly defined responsibilities and which might even be reusable across multiple applications.
So what are web components about? Roughly speaking, it’s about defining custom HTML tags and their corresponding behavior. Like..
<google-map pointer="46.471089,11.332816"></google-map>
It’s a powerful way to express semantics, isn’t it? By simply looking at this HTML tag, we know that it’ll render a google map most probably and set a pointer at the given coordinates. Neat! Currently this isn’t something the browser understands natively, although there’s a draft spec document on the w3c website on the web component standard and what concepts it should embrace.
You may also want to check out Polymer and webcomponents.org
Free sample from my video course where I explain different ways of creating components
Angular 2 fully embraces this component based development style. In fact, already since the beginning of Angular 1.x, allowing the user to define custom HTML elements with behavior was one of the core philosophies of the framework. A simple component in Angular 2 looks like this:
@Component({
selector: 'hello-world',
template: `<p>Hello, world!</p>`
})
class HelloWorldComponent {
}
In the corresponding HTML you would write this to instantiate it.
<hello-world></hello-world>
As you can see, decorators are being used to add meta information about the tag of the component, about the template that should be rendered and much more (which aren’t being used in this basic example here).
“Components are 1st class citizens in Angular 2”
Now with components being a 1st class citizen in Angular 2, there’s the concept of the so-called component-tree. Every Angular 2 application consists of such a component tree, having a top-level “application component” or root component and from there, lots of child and sibling components.
For example:
And this could then be mapped to HTML code like as follows.
The component tree is of major importance in Angular 2 and you will always again come across it. For example, this is how you compose your application, and the arcs from one component to the other are the way data is assumed to flow through your application as well as what Angular uses for performing change detection.
Excellent article by Pascal Precht on how change detection works in Angular 2
“Change detection” is the mechanism by which Angular determines which components need to be refreshed as a result of changes in the data of the application.
Templates and Data Binding
Obviously, when we write something like <hello-world></hello-world>
, we also need to define somewhere what Angular should render in place. That’s where templates and data binding come into play. As we’ve seen before, we define the template directly in the @Component({})
annotation by either using the template
or templateUrl
property, depending on whether we want to define it inline or load it from some url.
@Component({
...
template: `
<p>Hello, world!</p>
`
})
class HelloWorldComponent {}
We also need some data binding mechanism to get data into this template and out of it again. Let’s look at an example:
{% raw %}
@Component({
selector: 'hello-world',
template: `
<p>Hello, {{ who }}</p>
`
})
class HelloWorldComponent {
who: string = 'Juri'
}
{% endraw %}
As you can see, the variable who
inside the component’s class gets bound to into the template. Whenever you change the value of who
, the template will automatically reflect that change.
Services and Dependency Injection
Besides components, Angular always had the concept of Services and Dependency Injection. So does Angular 2. While the component is meant to deal with the UI and related stuff, the service is the place where you put your “business logic” s.t. it can be shared and consumed by multiple components. A service is nothing else than a simple ES6 class:
@Injectable()
export class PersonService {
fetchAllPeople() { ... }
}
From within some component we can then use this service
import { PersonService } from './services/person.service';
@Component({
...
providers: [ PersonService ]
})
class PersonComponent {
people;
constructor(private personService: PersonService) {
// DI in all it's beauty, just provide TS type annotation and Angular will handle the rest
// like adding the reference of personService to the class
// no need for "this.personService = personService;"
}
ngOnInit() {
this.people = this.personService.fetchAllPeople();
}
}
Nice, we get a reference to PersonService
from within our component. But wait, who instantiates the class? You guessed it, Angular’s dependency injection. For this to work you need two things
- add the
@Injectable
annotation - register
PersonService
as a provider either on the app, the top level component or from the part of the component tree (downwards) where you want to have the service injectable
Awesome introduction to how dependency injection works in Angular 2 by Pascal Precht on the Thoughtram blog.
Reactive Programming with RxJs 5 and Http
Angular 2 heavily uses a paradigm called “Reactive Programming”, in particular this is implemented through the RxJS 5 library. Like the Angular 2 http service won’t return promises, but instead RxJS Observables.
This pattern is not new at all, and gained a lot of popularity recently in modern frontend development. I’m not going into the details here now, as it would be an entire article on its own. Just know that Angular 2 will heavily rely on it and that’s why you should probably go and learn more about it.
Here are some good articles to get started :smiley:
André Staltz introduces the very basics of what reactive programming is all about.
A complete list of RxJS 5 operators with easy to understand explanations and runnable examples.
How to use observable sequences in AngularJS, an introduction by Gerard Sans.
Screencast from Cory Rylan where he demoes RxJS with Angular 2.
We will also briefly touch it in the screencast at the end of the article.
Lot’s of stuff, let’s get started with some code
In recent years, getting started quickly with frontend development got notably more difficult. Just creating some index.html
with a couple of <script>
tags is by far no more enough. What you need is some transpiler and a build tool that transpiles the code and serves it up, not to mention then optimizations like minification, inclusion of HTML templates, CSS compilation etc..
Some build tools/module bundlers you should definitely take a closer look at is SystemJS and Webpack. These are currently at the base of most Angular 2 projects. To make this easier, the Angular CLI project has been created. Mike Brocchi, core contributor of the CLI project demoed it at NGConf 2016.
The CLI allows to do things like
$ ng new my-super-awesome-project
$ ng g component my-new-component
$ ng g route hero
Moreover it generates these components by following the official styleguide and has even linting built-in.
Angular CLI is still under heavy development and has still some way to go till it’s fully usable. But it’s awesome for quickly getting started, and I’m quite sure it’ll get better and be a huge help especially for newcomers to get started with Angular 2 without having to know all the tooling in depth (recently Webstorm integrated Angular CLI support). However, I also strongly recommend to learn these tools as you go along. The CLI will bring you quickly to a good point, but it’s indispensable to know your tooling to get further ahead.
Other popular starters you definitely also want to take a look at are these. They are community based, have lots of best practices bundled and have been around for quite a while now.
An Angular 2 Starter kit featuring Angular 2 (Router, Http, Forms, Services, Tests, E2E, Dev/Prod), Material Design, Karma, Protractor, Jasmine, Istanbul, TypeScript, TsLint, Codelyzer, Hot Module Replacement, Typings, and Webpack by @AngularClass
Modular seed project for Angular 2 apps with fast, statically typed build
Okay..we’re now all set up I guess. Time to code!
Are you ready? Great, so let’s create our first Angular 2 application, step by step 👍.
Conclusion
Congrats, you’ve come to the end 😉. So by now you probably realize there’s lots of new stuff for you to learn. But the nice thing is that maybe it isn’t even only Angular 2 related. Like switching to ES2015 (ES6) and/or TypeScript, or adopting the reactive programming style with RxJS, or learn new toolings like Webpack and SystemJS…these are all things you can totally reuse, even though you dont’ plan to continue with Angular 2 in the end. Fortunately, the things you have to exclusively learn for Angular 2 got a lot smaller compared to Angular 1.x!
So this was basically just the beginning. From here you can start go more in depth. Follow the links I provided to get started. Also, feel free to drop me a line on Twitter. In general, try to connect with the Angular 2 community (over Twitter, GitHub, Slack,…), there are lots and lots of awesome people willing to help you with their enourmous expertise. :smiley:
Thanks to Martin Hochel for reviewing this article 👍