Professional Documents
Culture Documents
Textbook Ang Book 2 The Complete Book On Angular 2 1St Edition Nate Murray Ebook All Chapter PDF
Textbook Ang Book 2 The Complete Book On Angular 2 1St Edition Nate Murray Ebook All Chapter PDF
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-nate-murray/
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-5-nathan-murray/
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-9-nathan-murray/
https://textbookfull.com/product/ng-book-the-complete-guide-to-
angular-11-felipe-coury/
ng book The Complete Book on AngularJS 1st Edition Ari
Lerner
https://textbookfull.com/product/ng-book-the-complete-book-on-
angularjs-1st-edition-ari-lerner/
https://textbookfull.com/product/angular-2-cookbook-frisbie/
https://textbookfull.com/product/angular-2-ui-development-
kasagoni/
https://textbookfull.com/product/marquise-mansion-on-the-hill-
book-2-1st-edition-chashiree-m-m-k-moore-m/
https://textbookfull.com/product/kovana-outsider-book-2-1st-
edition-aiden-phoenix/
ng-book 2
Felipe Coury, Ari Lerner, Nate Murray, & Carlos Taborda
© 2015 - 2016 Felipe Coury, Ari Lerner, Nate Murray, & Carlos Taborda
Contents
Book Revision . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Prerelease . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Bug Reports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Chat With The Community! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Be notified of updates via Twitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
We’d love to hear from you! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Angular 2 is built in TypeScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
What do we get with TypeScript? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Trying it out with a REPL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Built-in types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Constructors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Fat Arrow Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
Template Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Wrapping up . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Component inputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Component outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Emitting Custom Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
Writing the ProductsList Controller Class . . . . . . . . . . . . . . . . . . . . . . . . 97
Writing the ProductsList View Template . . . . . . . . . . . . . . . . . . . . . . . . 98
The Full ProductsList Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
The ProductRow Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
ProductRow Component Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . 103
ProductRow Component Definition Class . . . . . . . . . . . . . . . . . . . . . . . . . 103
ProductRow template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
ProductRow Full Listing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
The ProductImage Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
The PriceDisplay Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
The ProductDepartment Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
NgModule and Booting the App . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Booting the app . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
The Completed Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
A Word on Data Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
HTTP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
Using @angular/http . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
import from @angular/http . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
A Basic Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
Building the SimpleHTTPComponent @Component . . . . . . . . . . . . . . . . . . . . . 157
Building the SimpleHTTPComponent template . . . . . . . . . . . . . . . . . . . . . . . 157
Building the SimpleHTTPComponent Controller . . . . . . . . . . . . . . . . . . . . . . 158
Full SimpleHTTPComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
Writing a YouTubeSearchComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
Writing a SearchResult . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Writing the YouTubeService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Writing the SearchBox . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
Writing SearchResultComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
Writing YouTubeSearchComponent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
@angular/http API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
Making a POST request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
PUT / PATCH / DELETE / HEAD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
RequestOptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
Routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
Why Do We Need Routing? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
How client-side routing works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
The beginning: using anchor tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
The evolution: HTML5 client-side routing . . . . . . . . . . . . . . . . . . . . . . . . 189
Writing our first routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Components of Angular 2 routing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Imports . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
Installing our Routes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
RouterOutlet using <router-outlet> . . . . . . . . . . . . . . . . . . . . . . . . . . 193
RouterLink using [routerLink] . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
CONTENTS
DoCheck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
AfterContentInit, AfterViewInit, AfterContentChecked and AfterViewChecked . . . . 484
Advanced Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
Rewriting ngIf - ngBookIf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
Rewriting ngFor - ngBookRepeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 495
Change Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
Customizing Change Detection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
Zones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
Observables and OnPush . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
Testing . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Test driven? . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
End-to-end vs. Unit Testing . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
Testing Tools . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Jasmine . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
Karma . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Writing Unit Tests . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Angular Unit testing framework . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 520
Setting Up Testing . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
Testing Services and HTTP . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
HTTP Considerations . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Stubs . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
Mocks . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
Http MockBackend . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
TestBed.configureTestingModule and Providers . . . . . . . . . . . . . . . . . . . . 527
Testing getTrack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
Testing Routing to Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
Creating a Router for Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535
Mocking dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Spies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
Back to Testing Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541
fakeAsync and advance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
inject . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
Testing ArtistComponent’s Initialization . . . . . . . . . . . . . . . . . . . . . . . . . 544
Testing ArtistComponent Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546
Testing ArtistComponent DOM Template Values . . . . . . . . . . . . . . . . . . . . . 547
Testing Forms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
Creating a ConsoleSpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
Installing the ConsoleSpy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
Configuring the Testing Module . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
Testing The Form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
Refactoring Our Form Test . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
CONTENTS
Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 39 - 2016-09-03 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 38 - 2016-08-29 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 37 - 2016-08-02 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 36 - 2016-07-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 35 - 2016-06-30 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 623
Revision 34 - 2016-06-15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624
Revision 33 - 2016-05-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624
Revision 32 - 2016-05-06 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 624
Revision 31 - 2016-04-28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 30 - 2016-04-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 29 - 2016-04-08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 28 - 2016-04-01 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 27 - 2016-03-25 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 26 - 2016-03-24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 25 - 2016-03-21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 24 - 2016-03-10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 23 - 2016-03-04 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625
Revision 22 - 2016-02-24 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Revision 21 - 2016-02-20 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Revision 20 - 2016-02-11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
Revision 19 - 2016-02-04 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 18 - 2016-01-29 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 17 - 2016-01-28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 16 - 2016-01-14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 15 - 2016-01-07 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 627
Revision 14 - 2015-12-23 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
Revision 13 - 2015-12-17 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
Revision 12 - 2015-11-16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 628
Revision 11 - 2015-11-09 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 629
Revision 10 - 2015-10-30 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 9 - 2015-10-15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 8 - 2015-10-08 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 7 - 2015-09-23 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 6 - 2015-08-28 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
Revision 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
Revision 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
Revision 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
Revision 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 631
CONTENTS 1
Book Revision
Revision 39 - Covers up to Angular 2 (2.0.0-rc.6, 2016-09-03)
Prerelease
This book is a prerelease version and a work-in-progress.
Bug Reports
If you’d like to report any bugs, typos, or suggestions just email us at: us@fullstack.io¹.
⁵
⁵mailto:carlos@ng-book.com
Writing your First Angular 2 Web
Application
Simple Reddit Clone
In this chapter we’re going to build an application that allows the user to post an article (with a
title and a URL) and then vote on the posts.
You can think of this app as the beginnings of a site like Reddit⁶ or Product Hunt⁷.
In this simple app we’re going to cover most of the essentials of Angular 2 including:
By the time you’re finished with this chapter you’ll have a good grasp on how to build basic Angular
2 applications.
Here’s a screenshot of what our app will look like when it’s done:
⁶http://reddit.com
⁷http://producthunt.com
Writing your First Angular 2 Web Application 2
Completed application
First, a user will submit a new link and after submitting the users will be able to upvote or downvote
each article. Each link will have a score and we can vote on which links we find useful.
Writing your First Angular 2 Web Application 3
In this project, and throughout the book, we’re going to use TypeScript. TypeScript is a superset of
JavaScript ES6 that adds types. We’re not going to talk about TypeScript in depth in this chapter, but
if you’re familiar with ES5 (“normal” javascript) / ES6 (ES2015) you should be able to follow along
without any problems.
We’ll go over TypeScript more in depth in the next chapter. So don’t worry if you’re having
trouble with some of the new syntax.
Writing your First Angular 2 Web Application 4
Getting started
TypeScript
To get started with TypeScript, you’ll need to have Node.js installed. There are a couple of different
ways you can install Node.js, so please refer to the Node.js website for detailed information:
https://nodejs.org/download/⁸ .
Do I have to use TypeScript? No, you don’t have to use TypeScript to use Angular 2, but
you probably should. ng2 does have an ES5 API, but Angular 2 is written in TypeScript
and generally that’s what everyone is using. We’re going to use TypeScript in this book
because it’s great and it makes working with Angular 2 easier. That said, it isn’t strictly
required.
Once you have Node.js setup, the next step is to install TypeScript. Make sure you install at least
version 1.7 or greater. To install it, run the following npm command:
npm is installed as part of Node.js. If you don’t have npm on your system, make sure you
used a Node.js installer that includes it.
Example Project
Now that you have your environment ready, let’s start writing our first Angular2 application!
Open up the code download that came with this book and unzip it. In your terminal, cd into the
first_app/angular2-reddit-base directory:
1 $ cd first_app/angular2-reddit-base
⁸https://nodejs.org/download/
⁹https://www.cygwin.com/
Writing your First Angular 2 Web Application 5
If you’re not familiar with cd, it stands for “change directory”. If you’re on a Mac try the
following:
1. Open up /Applications/Utilities/Terminal.app
2. Type cd, without hitting enter
3. In the Finder, Drag the first_app/angular2-reddit-base folder on to your termi-
nal window
4. Hit Enter Now you are cded into the proper directory and you can move on to the
next step!
1 $ npm install
Create a new index.html file in the root of the project and add some basic structure:
1 <!doctype html>
2 <html>
3 <head>
4 <title>Angular 2 - Simple Reddit</title>
5 </head>
6 <body>
7 </body>
8 </html>
1 .
2 |-- README.md // A helpful readme
3 |-- index.html // Your index file
4 |-- index-full.html // Sample index file
5 |-- node_modules/ // installed dependencies
6 |-- package.json // npm configuration
7 |-- resources/ // images etc.
8 |-- styles.css // stylesheet
9 |-- tsconfig.json // compiler configuration
10 `-- tslint.json // code-style guidelines
Angular 2 itself is a JavaScript file. So we need to add a script tag to our index.html document
to include it. But Angular has some dependencies itself:
Writing your First Angular 2 Web Application 6
Angular’s Dependencies
You don’t strictly need to understand these dependencies in-depth in order to use Angular
2, but you do need to include them. Feel free to skip this section if you’re not that interested
in the dependencies, but make sure you copy and paste these script tags.
• core-js
• zone.js
• reflect-metadata
• SystemJS
1 <script src="node_modules/core-js/client/shim.min.js"></script>
2 <script src="node_modules/zone.js/dist/zone.js"></script>
3 <script src="node_modules/reflect-metadata/Reflect.js"></script>
4 <script src="node_modules/systemjs/dist/system.src.js"></script>
Notice that we’re loading these .js files directly from a directory called node_-
modules. The node_modules directory will be created when you run npm install. If
you don’t have a node_modules directory, make sure your shell was “in” the directory
angular2-reddit-base (e.g. by using cd angular2-reddit-base) when you typed npm
install.
ES6 provides shims so that legacy JavaScript engines behave as closely as possible to ECMAScript 6.
This shim isn’t strictly needed for newer versions of Safari, Chrome, etc. but it is required for older
versions of IE.
What’s a shim? Perhaps you’ve heard about shims or polyfills and you’re not sure what
they are. A shim is code that helps adapt between cross browsers to a standardized behavior.
For instance, check out this ES6 Compatibility Table¹⁰. Not every browser is completely
compatible with every feature. By using different shims we’re able to get standardized
behavior across different browsers (and environments).
See also: What is the difference between a shim and a polyfill?¹¹
¹⁰https://kangax.github.io/compat-table/es6/
¹¹http://www.2ality.com/2011/12/shim-vs-polyfill.html
Writing your First Angular 2 Web Application 7
Zones
Zone.js¹³ is an advanced topic that we don’t need to worry about much here. For know, just know
that it is a library used by Angular, primarily for detecting changes to data. (If you’re coming from
Angular 1, you can think of zones as an automatic version of $digest. If you’re not coming from
Angular 1, you can ignore it for now.)
Reflect Metadata
Angular itself was written in Typescript, and Typescript provides annotations for adding metadata
to code. Roughly speaking, the reflect-metadata package is a polyfill that lets us use this metadata.
SystemJS
SystemJS is a module loader. That is, it helps us create modules and resolve dependencies. Module
loading in browser-side javascript is surprisingly complicated and SystemJS makes the process much
easier.
1 <!doctype html>
2 <html>
3 <head>
4 <title>Angular 2 - Simple Reddit</title>
5 <!-- Libraries -->
6 <script src="node_modules/core-js/client/shim.min.js"></script>
7 <script src="node_modules/zone.js/dist/zone.js"></script>
8 <script src="node_modules/reflect-metadata/Reflect.js"></script>
9 <script src="node_modules/systemjs/dist/system.src.js"></script>
10
11 </head>
12 <body>
13 </body>
14 </html>
Adding CSS
We also want to add some CSS styling so that our app isn’t completely unstyled. Let’s include two
stylesheets as well:
¹²https://github.com/zloirock/core-js
¹³https://github.com/angular/zone.js/
Writing your First Angular 2 Web Application 8
1 <!doctype html>
2 <html>
3 <head>
4 <title>Angular 2 - Simple Reddit</title>
5 <!-- Libraries -->
6 <script src="node_modules/core-js/client/shim.min.js"></script>
7 <script src="node_modules/zone.js/dist/zone.js"></script>
8 <script src="node_modules/reflect-metadata/Reflect.js"></script>
9 <script src="node_modules/systemjs/dist/system.src.js"></script>
10
11 <!-- Stylesheet -->
12 <link rel="stylesheet" type="text/css"
13 href="resources/vendor/semantic.min.css">
14 <link rel="stylesheet" type="text/css" href="styles.css">
15 </head>
16 <body>
17 </body>
18 </html>
For this project we’re going to be using Semantic-UI¹⁴ to help with the styling. Semantic-UI
is a CSS framework, similar to Foundation or Twitter Bootstrap. We’ve included it in the
sample code download so all you need to do is add the link tag.
Notice that we suffix our TypeScript file with .ts instead of .js The problem is our browser
doesn’t know how to interpret TypeScript files. To solve this, we’ll compile our .ts to a
.js file in just a few minutes.
¹⁴http://semantic-ui.com/
Writing your First Angular 2 Web Application 9
code/first_app/angular2-reddit-base/app.ts
1 /**
2 * A basic hello-world Angular 2 app
3 */
4 import {
5 NgModule,
6 Component
7 } from '@angular/core';
8 import { BrowserModule } from '@angular/platform-browser';
9 import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
10
11 @Component({
12 selector: 'hello-world',
13 template: `
14 <div>
15 Hello world
16 </div>
17 `
18 })
19 class HelloWorld {
20 }
21
22 @NgModule({
23 declarations: [ HelloWorld ],
24 imports: [ BrowserModule ],
25 bootstrap: [ HelloWorld ],
26 })
27 class HelloWorldAppModule {}
28
29 platformBrowserDynamic().bootstrapModule(HelloWorldAppModule);
This snippet may seem scary at first, but don’t worry. We’re going to walk through it step by step.
The import statements define the modules we want to use to write our code. Here we’re importing
four things: NgModule, Component, BrowserModule, and platformBrowserDynamic. We’ll be going
over each of these things in depth, so don’t worry if you aren’t sure what they do yet.
We import NgModule, Component from the module "@angular/core". The "@angular/core" portion
tells our program where to find the dependencies that we’re looking for.
Similarly, we import BrowserModule from the module "@angular/platform-browser" and plat-
formBrowserDynamic from the module "@angular/platform-browser-dynamic". We’ll talk about
these in a minute.
Writing your First Angular 2 Web Application 10
Notice that the structure of this import is of the format import { things } from wherever. In the
{ things } part what we are doing is called destructuring. Destructuring is a feature provided ES6
and we talk more about it in the next chapter.
The idea with the import is a lot like import in Java or require in Ruby: we’re pulling in these
dependencies from another module and making these dependencies available for use in this file.
Making a Component
One of the big ideas behind Angular 2 is the idea of components.
In our Angular apps we write HTML markup that becomes our interactive application. But the
browser only knows so many tags: the built-ins like <select> or <form> or <video> all have
functionality defined by our browser creator. But what if we want to teach the browser new tags?
What if we wanted to have a <weather> tag that shows the weather? Or what if we wanted to have
a <login> tag that creates a login panel?
That is the idea behind components: we teach the browser new tags that have new functionality.
If you have a background in Angular 1, Components are the new version of directives.
Let’s create our very first component. When we have this component written, we will be able to use
it in our HTML document like so:
1 <hello-world></hello-world>
So how do we actually define a new Component? A basic Component has two parts:
1. A Component annotation
2. A component definition class
1 @Component({
2 // ...
3 })
Writing your First Angular 2 Web Application 11
What is going on here? Well if you have a Java background it may look familiar to you: they are
annotations.
Think of annotations as metadata added to your code. When we use @Component on the HelloWorld
class, we are “decorating” the HelloWorld as a Component.
We want to be able to use this component in our markup by using a <hello-world> tag. To do that
we configure the @Component and specify the selector as hello-world.
1 @Component({
2 selector: 'hello-world'
3 })
If you’re familiar with CSS selectors, XPath, or JQuery selectors you’ll know that there are lots of
ways to configure a selector. Angular adds its own special sauce to the selector mix, and we’ll cover
that later on. For now, just know that in this case we’re defining a new tag.
The selector property here indicates which DOM element this component is going to use. This way
if we have any <hello-world></hello-world> tag within a template, it will be compiled using this
Component class.
Adding a template
We can add a template to our @Component by passing the template option:
1 @Component({
2 selector: 'hello-world',
3 template: `
4 <div>
5 Hello world
6 </div>
7 `
8 })
Notice that we’re defining our template string between backticks (` … `). This is a new (and
fantastic) feature of ES6 that allows us to do multiline strings. Using backticks for multiline strings
makes it easy to put templates inside your code files.
Writing your First Angular 2 Web Application 12
Should I really be putting templates in my code files? The answer is: it depends. For
a long time the commonly held belief was that you should keep your code and templates
separate. While this might be easier for some teams, for some projects it adds overhead
because you have switch between a lot of files.
Personally, if my templates are shorter than a page I much prefer to have the templates
alongside the code (that is, within the .ts file). When I can see both the logic and the view
together and it’s easy to understand how they interact with one another.
The biggest drawback to putting your views inlined with your code is that many editors
don’t support syntax highlighting of the internal strings (yet). Hopefully we’ll see more
editors supporting syntax highlighting HTML within template strings soon.
If you want to separate your template into a different file you can use the templateUrl key
to specify the URL of a template that will be loaded. More on this later.
code/first_app/angular2-reddit-base/app.ts
22 @NgModule({
23 declarations: [ HelloWorld ],
24 imports: [ BrowserModule ],
25 bootstrap: [ HelloWorld ],
26 })
27 class HelloWorldAppModule {}
28
29 platformBrowserDynamic().bootstrapModule(HelloWorldAppModule);
The first thing we see is an @NgModule annotation. Like all annotations, this @NgModule( ... ) code
adds metadata to the class immediately following (HelloWorldAppModule).
Writing your First Angular 2 Web Application 13
Our @NgModule annotation has three keys: declarations, imports, and bootstrap.
declarations defines the components in this module. In this case, we just have one, but you often
have several.
imports describes which dependencies this module has. We’re creating a browser app, so we want
to import the BrowserModule.
bootstrap tells Angular that when this module is used to bootstrap an app, we and to load the
HelloWorld component as the top-level component.
Now that we have our @NgModule defined, we can boot the app. The last line does this.
Remember that Angular can run on different platforms and so when we say platformBrowser-
Dynamic() we’re telling Angular that we’re using a browser and we want to compile Angular
“dynamically” (e.g. when we open the page in our browser vs. ahead-of-time compiling, which
we’ll talk more about much later).
Now that we have a platform, we call .bootstrapModule() and give it our HelloWorldAppModule
as the starting point.
Once the application is bootstrapped, the HelloWorld component will be rendered where the <hello-
world></hello-world> snippet is on the index.html file. Let’s try it out!