Angular2 PDF
Angular2 PDF
Sebastian Eschweiler
2015 - 2016 Sebastian Eschweiler
Tweet This Book!
Please help Sebastian Eschweiler by spreading the word about this book on Twitter!
The suggested hashtag for this book is #angular2book.
Find out what other people are saying about the book by clicking on this link to search for this
hashtag on Twitter:
https://twitter.com/search?q=#angular2book
Contents
DatePipe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
AsyncPipe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
JsonPipe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
SlicePipe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
Custom Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Implementing Custom Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
Pure And Impure Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Pure Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Impure Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
Comparing Pure And Impure Pipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
GitHub . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
As you can see the sample application is a simple Todo application. The user is able to add new
todo items by using the input field and clicking on button Add Todo. The output will be updated
automatically after a new todo item has been added. The item will be printed out in the list and the
total number of todos will increase.
Chapter 02: Writing your First Angular 2 Application 5
1 {
2 "name": "app02-01",
3 "version": "1.0.0",
4 "scripts": {
5 "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
6 "lite": "lite-server",
7 "postinstall": "typings install",
8 "tsc": "tsc",
9 "tsc:w": "tsc -w",
10 "typings": "typings"
11 },
12 "license": "ISC",
13 "dependencies": {
14 "@angular/common": "2.0.0",
15 "@angular/compiler": "2.0.0",
16 "@angular/core": "2.0.0",
17 "@angular/forms": "2.0.0",
18 "@angular/http": "2.0.0",
19 "@angular/platform-browser": "2.0.0",
20 "@angular/platform-browser-dynamic": "2.0.0",
21 "@angular/router": "3.0.0",
22 "@angular/upgrade": "2.0.0",
23 "core-js": "^2.4.1",
24 "reflect-metadata": "^0.1.3",
25 "rxjs": "5.0.0-beta.12",
26 "systemjs": "0.19.27",
27 "zone.js": "^0.6.23",
28 "angular2-in-memory-web-api": "0.0.20",
29 "bootstrap": "^3.3.6"
Chapter 02: Writing your First Angular 2 Application 6
30 },
31 "devDependencies": {
32 "concurrently": "^2.2.0",
33 "lite-server": "^2.2.2",
34 "typescript": "^2.0.2",
35 "typings":"^1.3.2"
36 }
37 }
As you can see, the package.json file is not only containing dependencies, but also some general
project information (name, version) and a scripts section. Within the scripts section we are defining
command shortcuts which can be executed via the npm command. We will get back to that section
and see how we can make use of these commands at the end of this chapter. The dependencies in
package.json are split up into two sections: dependencies and devDependencies. The first section
contains all dependencies which are used in our application to implement the functionality we want
to have. For example you can find entries for the Angular and the Bootstrap framework here. In
contrast, the devDependencies section is listing the dependencies which are required at development
time only. In the example from above you can see that four development dependencies are listed:
concurrently, lite-server, typescript and typings.
The typescript package contains the TypeScript compiler that enables us to use TypeScript
elements in our code. The compiler runs before the application files are sent to the browser
and transforms TypeScript to valid JavaScript code, so that the browser is able to interpret our
scripts.
The lite-server package contains a lightweight development Node.js server that serves a web
app, opens it in the browser, refreshes when html or javascript change, injects CSS changes
using sockets, and has a fallback page when a route is not found.
With the concurrently package installed, we can execute two npm commands at the same
time. This is great, especially for Angular 2, because we always need to perform two steps:
run the TypeScript compiler and then execute the lite-server to deliver our application to the
browser. Instead of opening up two terminals and executing the two commands seperatly,
concurrently lets us do this in one step by using the concurrent command.
The typings package installs the typings command which helps to manage TypeScript
definition files for your project. The command uses the typings.json configuration file.
Now, that all of the dependencies of our project are listed in package.json we can perform the
installation by only executing one single command in the project directly:
$ npm install
Thats it! No more steps needed. The command will read in the dependencies defined in package.json
and will automatically install one after another in the node_modules subfolder in your project.
Chapter 02: Writing your First Angular 2 Application 7
The JSON structure consists of two sections. The first section is named compilerOptions and contains
command line options which are passed to the TypeScript compiler every time the program is
executed. Please note, that we use the compiler option target to specify that we want to get our
TypeScript code compiled to ECMAScript 5. Herewith it is ensured that the resulting JavaScript
code can be interpreted by modern browsers even if they are not supporting ECMAScript 2015 yet.
If you want to have additional information about the meaning of the various TypeScript compiler
options please take a look at https://github.com/Microsoft/TypeScript/wiki/Compiler-Options.
SystemJS Configuration
SystemJS is a dynamic module loader that also works with ECMAScript 2015 modules and is a good
choice for Angular2 projects. If you prefer another loader you can skip SystemJS and install the
loader you like most (e.g. webpack).
Chapter 02: Writing your First Angular 2 Application 8
In the examples of this book well be using SystemJS. SystemJS needs to be configured. Therefore
the file systemjs.config.js must be added to the root of your project and the following configuration
code needs to be included:
1 /**
2 * System configuration for Angular 2 samples
3 * Adjust as necessary for your application needs.
4 */
5 (function (global) {
6 System.config({
7 paths: {
8 // paths serve as alias
9 'npm:': 'node_modules/'
10 },
11 // map tells the System loader where to look for things
12 map: {
13 // our app is within the app folder
14 app: 'app',
15 // angular bundles
16 '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
17 '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
18 '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
19 '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platfo\
20 rm-browser.umd.js',
21 '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynami\
22 c/bundles/platform-browser-dynamic.umd.js',
23 '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
24 '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
25 '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
26 // other libraries
27 'rxjs': 'npm:rxjs',
28 'angular2-in-memory-web-api': 'npm:angular2-in-memory-web-api',
29 },
30 // packages tells the System loader how to load when no filename and/or no e\
31 xtension
32 packages: {
33 app: {
34 main: './main.js',
35 defaultExtension: 'js'
36 },
37 rxjs: {
Chapter 02: Writing your First Angular 2 Application 9
38 defaultExtension: 'js'
39 },
40 'angular2-in-memory-web-api': {
41 main: './index.js',
42 defaultExtension: 'js'
43 }
44 }
45 });
46 })(this);
The configuration code is a bit complicated to read. The first think you should notice is the a map
object is created and filled with properties.
Now, that we have everything installed and configured correctly were ready to start the implemen-
tation of our first Angular 2 application. Herewith we tell SystemJS where to look when we import
modules. E.g. if were importing from @angular in our components were actually importing from
the node_modules/@angular folder.
The next thing the configuration code is doing is to register all packages which may be used in the
project. The packages are stored in the packages object.
Finally, both configuration objects (map and packages) are added the config object. As a parameter
this object is passed to the call of System.config.
Implementation
First of all, we need to implement the main HTML file of the project and include the external libraries
needed. Create the index.html in the root project folder and insert the following HTML code:
1 <html>
2 <head>
3 <title>Angular 2 QuickStart</title>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1">
6 <link rel="stylesheet" href="styles.css">
7 <! 1. Load libraries -->
8 <! Polyfill(s) for older browsers -->
9 <script src="node_modules/core-js/client/shim.min.js"></script>
10 <script src="node_modules/zone.js/dist/zone.js"></script>
11 <script src="node_modules/reflect-metadata/Reflect.js"></script>
12 <script src="node_modules/systemjs/dist/system.src.js"></script>
Chapter 02: Writing your First Angular 2 Application 10
13
14 <! Bootstrap -->
15 <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
16 <link href="node_modules/bootstrap/dist/css/bootstrap.min.css" rel="styleshe\
17 et">
18
19 <! 2. Configure SystemJS -->
20 <script src="systemjs.config.js"></script>
21 <script>
22 System.import('app').catch(function(err){ console.error(err); });
23 </script>
24 </head>
25
26 <body>
27 <div class="container">
28 <h1>Learning Angular 2 <small>Chapter 02</small></h1>
29 <my-app>Loading ...</my-app>
30 </div>
31 </body>
32 </html>
As you can see were using various <script> tags point to external libraries in subfolder node_-
modules. These are the libraries which we installed via NPM in the last section and now include in
our web application to make use of them. Furthermore you find an additional script element in the
header section which included the SystemJS configuration file which weve created in the previous
step.
Furthermore the app module is imported and run.
Implementing AppModule
Create the project subfolder app and start by using the following code to implement the application
module for our application in file app/app.module.ts:
Chapter 02: Writing your First Angular 2 Application 11
By using Angular 2 modules it is possible to consolidate components, directives and pipes into
cohesive blocks of functionality. Each Angular 2 application has at least one module: the application
module or root module. This application module has the conventional name of AppModule and is
implemented in the file app.module.ts. As every module the application module is implemented
by using a class and attaching the @NgModule decorator as you can see in the code listing. This
decorator is imported from @angular/core. Within the decorator block you can find the following
properties which are used for configuration:
declarations: The array which is assigned to the declarations property contains all compo-
nents, directives and pipes which belong to that module.
imports: The imports array is used to list all dependencies (other modules) which needs to be
made available to the module. Every application module needs to import BrowserModule. By
importing this standard module we get access to browser specific renderers and Angular 2
standard directives like ngIf and ngFor.
bootstrap: The bootstrap property is only used in application / root modules and contains
the component of the module which should be loaded first when bootstrapping the app. The
example from above defines that AppComponent should be loaded first. Of course this is no
surprise as this is the only component of our sample app.
exports: This property can be used when declaring function modules. Function modules can
be imported by the application module or other function modules and comprise components,
directives and pipes (and even services) which belong to a certain functionality. The exports
property contains a list of components, directives and pipes the importing module can use. In
fact that is the modules public API.
providers: A list of dependency injection providers (e.g. service classes) which are part of the
module. These providers are automatically registered with the root injector of the modules
execution context. Dont be confused by the terms dependency injection, providers and
injectors. Well cover those things in chapter chapter 8 in detail.
Chapter 02: Writing your First Angular 2 Application 12
Implementing AppComponent
Next, use the following code to implement the basic structure of our main Angular 2 component in
file app/app.component.ts:
The first line of the code shows an ECMAScript 2015 import statement which is used to include the
standard Angular Component decorator. With the decorator available, the Angular 2 component is
implemented as a class. The class only contains an empty constructor and the decorator is added
(@Component). If you are familiar with Angular 1.x you can compare components with the concept
of directives in Angular 1.x. Every Angular 2 application is built by implementing components.
Components are organized in a hierarchical way, so that the Angular 2 application always starts with
one main component. Further components are used by the main components or by child components
of the main components, so that we end up with a tree of components in an typical Angular 2
application. Inside the @Component-Annotation we use the selector property to define the name
of the HTML-Element which should be used to include this component. In this current example we
set the value for the selector property to my-app. With this setting in place we are able to use the
component in our HTML document like so:
<my-app></my-app>
Furthermore the @Component annotation is containing the template properties. The value which
is assigned to the template property is an empty string. In the next step we will replace the empty
string with the HTML template code which is needed to generate the output of the component.
1 template: `
2 <h4>Todos List</h4>
3 <h5>Number of Todos: <span class="badge">{{todos.length}}</span></h5>
4 <ul class="list-group">
5 <li *ngFor="let todo of todos" class="list-group-item">
6 {{todo}}
7 </li>
8 </ul>
9 <div class="form-inline">
10 <input class="form-control" #todotext>
11 <button class="btn btn-default" (click)="addTodo(todotext.value)">Add Todo</\
12 button>
13 </div>
14 `
The value which is assigned to the template property is now a string containing the HTML template
code which should be used as the components view. We are using the new EcmaScript 2015 template
string feature to assign a multiline string containing the template code. In order to make use of this
feature the multiline string has to start and end with backticks (). The first information which is
printed out by the template is the total number of todo items available. All todo items will be stored
in an array of strings named todos. To get the total number of items we can use the length property
of the todos array. To access the property value the expression is included in the template by using
double curly braces:
{{todos.length}}
This is the syntax which is used to include the result of an expression in the HTML output which is
generated when the component is used in the application. Next, a list of all todo items is generated
by using a <ul> element. Each list item is represented by a <li> child-element. The ngFor directive
helps us to generate <il> elements for each data item by iterating over the todos array:
The syntax which is used here is *ngFor="let todo of todos" and is applied on the <li> element.
For every element found in todos array the output of the element (and its content) is repeated.
For each iteration the current todo item is available through the variable todo, so that we can
access the todo text directly by using again the expression syntax {{todo}}. Please be aware: the
ngFor directive is available because weve imported BrowserModule in our root application module
AppModule. This makes Angular 2 standard directives available in all templates of components
Chapter 02: Writing your First Angular 2 Application 14
listed in the declarations property of the @NgModule decorator. After the list of todos the template
contains an input element and a button so that the user is able to add new todo elements. Notice that
the <input> element is containing the attribute #todotext. This is the syntax which is used in Angular
2 to create a variable todotext which is accessible in the component class and gives us access to the
HTML element. The <button> element is containing another special attribute: (click). This notation
is used in Angular 2 to describe events. The value which is assigend to the click event is a string
containing an event handler method named addTodo. This method is not yet available and will be
implemented in the next step. The addTodo method gets one parameter: todotext.value. Here we are
using the previously assigned variable todotext and access the user input value by using the property
value.
So the view implementation for our component is ready now. The last thing we have to do is to
adapt the MyApp component class a little bit to meet the expectations the template code has set.
First we need to have an todos array in place containing all our todo items:
As you can see we are using TypeScript here to declare a typed array of type Array<string>. The
class constructor is used to initialize the todos array with three items. If you try to assign anything
other as a string to the array the TypeScript compiler will run into an error because the type check
fails. The addTodo method is implemented in class AppComponent, so that we can use this method
to handle the click event of the button. Again, we are using TypeScript to declare that the todo
parameter must be of type string. The method takes this string and calls the push method to extend
the todos array with this new item. Another thing to notice here is that the class keyword is preceded
by export. Herewith we make the AppComponent available as a module, so that we can import
AppComponent in another file by using the SystemJS module loader.
As you can see the file main.ts is quite comprehensive, only three lines of code are needed. First
were importing platformBrowserDynamic and AppModule. By importing platformBrowserDynamic
we get access to the Just-In-Time (JIT) compiler which compiles the application in the browser. By
executing
platformBrowserDynamic().bootstrapModule(AppModule);
were telling the Just-In-Time compiler to start the application by first compiling and loading
AppModule. To determine what needs to be displayed to the user, the compiler looks for the value
which has been passed to the AppModules bootstrap property:
bootstrap: [AppComponent]
In our case weve been passing AppComponent. Now this tells the Just-In-Time compiler that
AppComponent needs to loaded first when bootstrapping with the AppModule. The code of the
component is compiled to JavaScript which can be interpreted by the Browser directly and the
corresponding template is used to generate the HTML output which is displayed to the user.
Luckily we have already set up NPM scripts for those tasks in package.json:
Chapter 02: Writing your First Angular 2 Application 16
...
"scripts": {
"start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
"lite": "lite-server",
"postinstall": "typings install",
"tsc": "tsc",
"tsc:w": "tsc -w",
"typings": "typings"
}
...
Here you can see that the scripts section of package.json contains NPM scripts definitions. Most of
the NPM scripts are executed by using the npm command in the following way:
$ npm run [script]
Some scripts (like start) dont rquire the run keyword and can be executed in the following way:
$ npm start
In the following you can find an overview of the NPM scripts defined:
Start the sample project by entering the project root folder on the command line and execute the
NPM start script:
In order to start our project with one single command (TypeScript compiler and lite-server at the
same time) we simply need to execute:
$ npm start
Executing this command should deliver a result similar to what you can see in the following
screenshot:
Chapter 02: Writing your First Angular 2 Application 17
The output shows that both, the TypeScript compiler and the web server, are running in parallel.
Every line which is printed on the console is prefixed with either [0] or [1]. With this information
available you can see from which process the outputted line is generated. Everything which starts
with [0] is outputted from the TypeScript server which is executed in watch mode. Everything which
starts with [1] is generated by lite-server.
The application is now up and running and can be opened by accessing URL http://localhost:3000 in
your browser. If you change HTML or TypeScript code in your project changes are processed by the
running TypeScript compiler in the background and pushed to the browser automatically without
the need of doing a manual refresh of the webpage.
To stop both processes simply hit keys CTRL+C in your terminal windows.
GitHub
The source code of this chapter is available on GitHub: https://github.com/seeschweiler/angular2-
book-chapter02