Loading...
Menu

Angular 2: From Theory To Practice

p(()).

COPYRIGHT

Copyright © 2016 Daolrevo Ltd trading as Code Craft

All rights reserved. This book or any portion thereof may not be reproduced or used in any manner whatsoever without the express written permission of the publisher except for the use of brief quotations in a book review.

codecraft.tv

CHANGELOG

1.0.1 (2017-01-05)

{color:#191918;}

  • {color:#191918;} Sample code and plunkers updated to Angular 2.4.1
  • {color:#191918;} Added practice activities to (most) sections.
  • {color:#191918;} Bug fix for child routing: empty child paths now also require a {color:#191918;}pathMatch: 'full' param to the route config.
  • {color:#191918;} Various spelling mistakes and typos corrected.

1.0.0 (2016-11-16)

{color:#191918;}

  • {color:#191918;} First Release supporting Angular 2.1.0

ABOUT

This book has been funded in large part through the generous support of my backers through kickstarter and is therefore released for FREE.

Please ensure you have the latest version by visiting ng2.codecraft.tv.

There is a also a video course version of this book, again please check ng2.codecraft.tv for details.

Cheers,

Asim Hussain

@jawache

OVERVIEW

The course is going to begin with a quickstart.

We use a web editor called plunker and create a basic Angular application from scratch.

In this quickstart you get a 50,000 foot view of the major features of Angular and since we use a web editor it means you can get stuck in writing code ASAP without having to spend ages setting up your computer.

Let’s get started!

PLUNKER

Later on I’ll be showing you how to install Angular and run the required development tools locally on your computer.

But for now we are going to use an online editor called plunker[http://plnkr.co/].

The goal of this chapter is to explain how plunker works and the different files that make up an Angular 2 plunker.

Learning Outcomes

{color:#191918;}

  • {color:#191918;} Understand what plunker is, why and how we use it.
  • {color:#191918;} Understand the structure of an Angular plunker.
  • {color:#191918;} Know what each of the included libraries do.

What is plunker and how to use it?

{color:#191918;}

  • {color:#191918;} It’s a web based editor and development environment. With it you can create, edit and run HTML, css and JavaScript files directly from your browser.
  • {color:#191918;} No setup required, everyone can code in the browser instantly.
  • {color:#191918;} Each plunker has it’s own unique URL which you can share with others so it’s a useful way to show others your work.
  • {color:#191918;} You can’t edit someone else’s plunker but you can fork it. Forking creates a new plunker that you own with all the files copied across.
  • {color:#191918;} If your plunker has an {color:#191918;}index.html file pressing the Run button will preview the plunker in the preview pane.

Structure of an Angular Plunker

An Angular 2 plunker is composed of:

{color:#191918;} {color:#191918;} index.html {color:#191918;} The main HTML file which includes the required libraries and bootstraps our Angular application {color:#191918;} script.ts {color:#191918;} The main file in which we’ll be placing our Angular 2 code {color:#191918;} system.config.js {color:#191918;} Configuration for SystemJS which handles module loading (*) and compilation of TypeScript into JavaScript {color:#191918;} tsconfig.json {color:#191918;} Configuration for the TypeScript transpiler (*)

(*) We will be covering these topics in more detail later.

In our index.html we are including 4 javascript files, like so:

{color:#191918;}
bc. {color:#191918;}  <script src="https://unpkg.com/core-js/client/shim.min.js"></script>
  <script src="https://unpkg.com/[email protected]?main=browser"></script>
  <script src="https://unpkg.com/[email protected]"></script>
  <script src="https://unpkg.com/[email protected]/dist/system.src.js"></script>pre

core-js

The version of javascript that has the broadest support across all browsers is ES5.

Then next version of javascript is ES6. ES6 does not have full support across all browsers yet. (See https://kangax.github.io/compat-table/es6/).

This library enables a browser which doesn’t have support for ES6 to run ES6 code, just maybe not in the most efficient way

For further details take a look at the project homepage: https://github.com/zloirock/core-js

zone

“Zone is a mechanism for intercepting and keeping track of asynchronous work” – https://github.com/angular/zone.js

You don’t need to know details about this yet, it’s an advanced topic, but to summarise.

One of the problems with Angular 1 was that Angular didn’t know when things happened outside of Angular, for example in asynchronous callbacks.

When Angular 1 knew about callbacks it could do wonderful things, like automatically update the page. When it didn’t know about callbacks it frustratingly didn’t update the page.

No matter how experienced you were with Angular 1 bugs with these kinds of issues cropped up time and time again.

Zones solves this problem, it keeps track of all pending asynchronous work and tells Angular when things happen. So in Angular 2 you don’t have to worry about whether Angular knows about your callback or not, zones tracks this for you and notifies Angular when something happens.

reflect

Angular 2 is written in TypeScript, this file lets us use a feature of TypeScript called annotations (or decorators).

You’ll learn a lot more about annotations later on in this course.

SystemJS

Instead of including all the files we need as script tags in our index.html, in Angular we break up all our code into files called modules. We then leave it to a module loader to load the modules when they are needed, in the order they are needed.

It’s a complicated problem, in a browser we can’t make hundreds of requests to load JavaScript modules one at a time when a module loader requests them so a module loader needs to be clever.

It will become part of the core JavaScript language but until then we use a module loader, there are several available but the one we use in our plunker is SystemJS.

{background:none;}

If we build an application locally with the Angular command line tools it will use another module loader called Webpack.

systemjs.config.js

SystemJS needs help to figure out when and how to load up certain modules, e.g. if we ask for a module called
bc. {color:#191918;}@angular what does that mean? What should it load up? Which version? This configuration is stored in the
bc. {color:#191918;}systemjs.config.js file.

System.import

Now we’ve loaded up the SystemJS library and configured it by loading up the
bc. {color:#191918;}systemjs.config.js file, we can use the
bc. {color:#191918;}System.import function to load up our
bc. {color:#191918;}script.ts file, like so:

{color:#191918;}
bc. {color:#191918;}System.import('script.ts').catch(function(err) {
  console.error(err);
});pre

Why not just add script.ts as a script tag?:

{color:#191918;}
bc. {color:#191918;}<script src="script.ts"></script>pre

Because in
bc. {color:#191918;}script.ts we include other modules, if we loaded via a script tag the browser doesn’t know how to load those other dependant js files.

By loading with
bc. {color:#191918;}System.import we make SystemJS figure out which dependant modules are required and loads the files for those automatically.

Summary

We can code up Angular in the browser using an online editor called plunker. It gives us the ability to try our Angular quickly without requiring complex setup.

It also gives us a unique URL so:

{color:#191918;}

  1. {color:#191918;}
    We can quickly take a look at some code another person has written.
  1. {color:#191918;}
    We can share our code with other people, which is especially useful when we are stuck with some broken code and need help.

Listing

http://plnkr.co/edit/NzQ1skgIrliMIGgEPkp8?p=preview

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
  <link rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">



pre

INTRO TO TYPESCRIPT

In this lecture we will explain what TypeScript is and how we can code a web application using TypeScript.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    Difference between TypeScript and JavaScript.
  • {color:#191918;}
    How we convert from TypeScript into JavaScript.

TypeScript vs JavaScript

From the previous lecture we named the file we are going to type our code into
bc. {color:#191918;}script.ts

The reason the file ends in
bc. {color:#191918;}.ts instead of
bc. {color:#191918;}.js is that Angular is written in a superset of JavaScript called TypeScript.

TypeScript is the ES6 version of JavaScript plus a few other TypeScript only features which Angular 2 needs in order to work.

You can write Angular applications in either TypeScript, ES6 or even ES5 JavaScript.

However Angular itself is written in TypeScript, most examples on the web are written in TypeScript, most Angular 2 jobs require you to write TypeScript so this book will be teaching in TypeScript.

Transpilation

Browsers don’t support TypeScript.

Browsers barely support ES6 JavaScript.
So how can we write our code in TypeScript?

We use something called a transpiler which converts from one language to another.

We can write in TypeScript and have a transpiler convert to ES6 or ES5.

{background:none;}

To understand why is it called transpilation and not compilation in more detail see https://www.stevefenton.co.uk/2012/11/compiling-vs-transpiling/

Since most browsers don’t support ES6 features yet we are going to transpile our TypeScript into ES5.

{background:none;}

Later on in the book I’m going to show you how to transpile TypeScript into JavaScript locally on your computer, but since we are using plunker we are using a feature of SystemJS which lets us transpile in the browser.

If we look at the
bc. {color:#191918;}tsconfig.json file in our demo plunker we can see there are a few settings we are using to convert TypeScript into JavaScript.

{color:#191918;}
bc. {color:#191918;}{
  "compilerOptions": {
    "target": "es5", [_{color:#468C54;}①_]
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
  }
}pre

{color:#191918;}

  1. {color:#191918;} As you can see the target is set to ES5.

Summary

{color:#191918;}

  • {color:#191918;}
    TypeScript is just JavaScript with a few more advanced features.
  • {color:#191918;}
    Browser can’t run TypeScript so we first need to transpile it into JavaScript.
  • {color:#191918;}
    The most common version of JavaScript is currently ES5 so we transpile TypeScript into ES5 JavaScript.

WRITING OUR FIRST APP

We want to create a simple app that displays a joke to the user.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    That Components are the building blocks of an Angular application.
  • {color:#191918;}
    What annotations are and how to use them in TypeScript.
  • {color:#191918;}
    How to import code from other files so we can use it in our file.
  • {color:#191918;}
    How to package our application into an Angular Module.
  • {color:#191918;}
    How to bootstrap an Angular application so is starts on a web page

Components

To begin writing our application we open up
bc. {color:#191918;}script.ts and create a class called
bc. {color:#191918;}JokeComponent.

{color:#191918;}
bc. {color:#191918;}class JokeComponent {
}pre

{background:none;}

A
bc. {color:#191918;}class is a new feature of ES6 which we will explain in much more detail in the next section, but to summarise it’s a blueprint for creating objects with specific functions and properties already attached to it.

The word
bc. {color:#191918;}Component isn’t random. Components are a feature of Angular that let us create a new HTML language and they are how we structure Angular applications.

HTML comes with a bunch of pre-built tags like
bc. {color:#191918;} and
bc. {color:#191918;}

 which look and behave a certain way. In Angular we create new custom tags with their own look and behaviour.

An Angular application is therefore just a set of custom tags that interact with each other, we call these tags Components.

{background:none;}

If you are coming from Angular 1 then Components are the same as Components in Angular 1.5 and the same as element directives in Angular <1.5

The code that controls a component we put into a class like the
bc. {color:#191918;}JokeComponent above, but how do we link this class with a HTML tag, say a tag called
bc. {color:#191918;}?

We use a new feature of TypeScript called annotations, and specifically an annotation called
bc. {color:#191918;}@Component, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke'
})
class JokeComponent {
}pre

The
bc. {color:#191918;}@Component is an annotation, an annotation automatically adds some boilerplate code to the class, function or property its attached to.

{background:none;}

You can write Angular without using annotations you would just have to write the boilerplate code yourself.

We are going to use other annotations later on, however the main one for working with components is
bc. {color:#191918;}@Component.

You can configure the Component annotation by passing it an object with various parameters. In our example above Component has one parameter called
bc. {color:#191918;}selector, this tells Angular 2 which tag to link this class too.

By setting the selector to
bc. {color:#191918;}joke we’ve told angular that whenever it finds a tag in the HTML like
bc. {color:#191918;} to use an instance of the JokeComponent class to control it.

Imports

Before we can use
bc. {color:#191918;}@Component though we need to import it, like so:

{color:#191918;}
bc. {color:#191918;}import { Component } from '@angular/core';pre

The line above is saying we want to import the
bc. {color:#191918;}Component code from the module
bc. {color:#191918;}@angular/core.

We leave to SystemJS to figure out how to load that component from angular/core or even [_where_] angular/core is.

{background:none;}

The above might not look like javascript but it is, the
bc. {color:#191918;}{ Component } part is something called destructuring and that’s a feature of ES6, more on that later.

If you are coming from a language like Python or Java you’ll be used to the concept of imports. Basically we are pulling in dependencies from another file and making it available in this file.

Template

To use our brand new custom component we add the tag
bc. {color:#191918;} to our HTML file, like so:

{color:#191918;}
bc. {color:#191918;}<body>
  <joke></joke>
</body>pre

So far this isn’t doing much yet though, we want Angular to replace with some template HTML. To do that we use another attribute of the Component decorator called template, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke',
  template: '<h1>What did the cheese say when it looked in the mirror?</h1><p>Halloumi (hello me)</p>'
})pre

That’s hard to read though, the HTML is all written on one line but i’d like to read it on multiple lines.

There is a new feature of ES6 JavaScript called
bc. {color:#191918;}template strings which lets us define multi-line strings, lets use it:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke',
  template: `
  <h1>What did the cheese say when it looked in the mirror?</h1>
  <p>Halloumi (hello me)</p>
  `
})pre

The string uses a special character
bc. {color:#191918;}` it’s called a back-tick, we’ll be digging into this in much more detail in the next section. For now just accept that it lets us define strings on multiple lines like the above.

Angular Modules

If we ran this code now we would see it’s still not working!

We’ve defined a component with a custom tag, added the tag to our HTML but we haven’t told Angular that we want to use Angular on this page.

To do that we need to do something called bootstrapping.

{background:none;}

In Angular 1 when we added
bc. {color:#191918;}np-app=“module-name“ to the top of the HTML page it bootstrapped the application for us. When Angular 1 loaded it first checked for this tag, looked for the module that was associated with that tag and loaded the code from it. However with Angular 2 we need to do all of this manually, for good reasons which we’ll explain later.

In Angular 2 your code is structured into
bc. {color:#191918;}packages called Angular Modules, or
bc. {color:#191918;}NgModules for short. Every app requires at least one module, the root module, that we call
bc. {color:#191918;}AppModule by convention.

{background:none;}

We are using the term module for two different concepts. In JavaScript the term module generally refers to code which exists in a single file. An NgModule is a different concept, it combines code from different files together into one package. An NgModule therefore contains functionality from multiple files a module refers to functionality in a single file.

Lets create our root Angular Module, like so:

{color:#191918;}
bc. {color:#191918;}@NgModule({
  imports: [BrowserModule],
  declarations: [JokeComponent],
  bootstrap: [JokeComponent]
})
export class AppModule {
}pre

To define an Angular Module we first create a class and then annotate it with a decorator called
bc. {color:#191918;}@NgModule.

{background:none;}

You’ll notice this follows a similar pattern to when we created a component. We created a class and then annotated it with a decorator, this pattern is a common one in Angular.

{color:#191918;}@NgModule has a few params:

{color:#191918;}
{color:#191918;}
imports

{color:#191918;} The other Angular Modules that export material we need in this Angular Module. Almost every application’s root module should import the BrowserModule.

{color:#191918;}
declarations

{color:#191918;} The list of components or directives belonging to this module.

{color:#191918;}
bootstrap

{color:#191918;} Identifies the root component that Angular should bootstrap when it starts the application.

We know
bc. {color:#191918;}NgModule but
bc. {color:#191918;}BrowserModule is the Angular Module that contains all the needed Angular bits and pieces to run our application in the browser.

Angular itself is split into separate Angular Modules so we only need to import the ones we really use. Some other common modules you’ll see in the future are the
bc. {color:#191918;}FormsModule,
bc. {color:#191918;}RouterModule and
bc. {color:#191918;}HttpModule.

We also need to remember to import NgModule and BrowserModule, like so:

{color:#191918;}
bc. {color:#191918;}import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';pre

Bootstrapping

Now we have defined our root Angular Module called AppModule we need to bootstrap the application using it, like so:

{color:#191918;}
bc. {color:#191918;}import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
.
.
.
platformBrowserDynamic().bootstrapModule(AppModule);pre

You might be asking yourself why Angular 2 doesn’t do this for us like it did in Angular 1?

In Angular 2 bootstrapping is platform specific.

Angular 1 assumed that Angular would only ever be run in a browser, Angular 2 makes no such assumption. We could be writing Angular 2 code for a mobile device using a solution like Ionic. We could be loading up Angular on a node server so we can render HTML for web crawlers that don’t run JavaScript.

Angular 2 isn’t limited to only working in the browser which is why we need to tell Angular exactly how we want it to bootstrap itself, in our case we are running in the browser so we use the platformBrowserDynamic function to bootstrap our application.

Component Tree

An Angular 2 application is architected as a tree of Components stemming from one root Component.

Your root component is the component you configured on your root
bc. {color:#191918;}NgModule in the bootstrap property, so in our case it’s the
bc. {color:#191918;}JokeComponent.

By bootstrapping with
bc. {color:#191918;}JokeComponent we are saying that it’s the root component for our application.

In the template for our
bc. {color:#191918;}JokeComponent we would add tags for other Components, in the template for those Components we would add tags for others… and so on and so on.

However in our
bc. {color:#191918;}index.html file we will never see anything other than the tag for our root component, like so:

{color:#191918;}
bc. {color:#191918;}<body>
  <joke></joke>
</body>pre

Running the application in our browser we would see:

Troubleshooting

If when looking at the browser console you see see an error like the below:

{color:#191918;}
bc. {color:#191918;}> The selector "joke" did not match any elementspre

This means you forgot to add the tag for your root component to your
bc. {color:#191918;}index.html file.

Summary

A Component is the building block of an Angular application.

It lets us create a new HTML language of custom tags and link them with javascript classes which describe the behaviour of that tag.

An application is composed of a tree of such Components glued together all depending from one root component.

We package together related Components and supporting code into something called an Angular Module which we use to bootstrap Angular onto a webpage.

Listing

http://plnkr.co/edit/X1PpIFrTgBZb22YsvLeo?p=preview

Listing 1. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
  <link rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">




pre

Listing 2. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {NgModule}      from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Component} from '@angular/core';

@Component({ selector: ‘joke’, template: `

What did the cheese say when it looked in the mirror?

Halloumi (Hello Me)

`
})
class JokeComponent {
}

@NgModule({ imports: [BrowserModule], declarations: [JokeComponent], bootstrap: [JokeComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

STRING INTERPOLATION

Start to make our application a bit more re-usable by storing the setup and punchline of our joke as properties on our component class instead of hardcoded in the HTML.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    Understand classes in more detail, how to define them and how to use them.
  • {color:#191918;}
    What is string interpolation and the moustache syntax
    bc. {color:#191918;}{{ }}

Motivation

In the previous chapter we created our first Angular application, a very simple one with only one component called
bc. {color:#191918;}JokeComponent with a tag of
bc. {color:#191918;}joke.

Now whenever we want to display that joke in our application we simply add the tag
bc. {color:#191918;} in our HTML.

But it’s not very re-usable, it just shows the same joke over and over again, a more re-usable
bc. {color:#191918;}JokeComponent would be one where the developer can use different jokes.

Firstly lets add some properties or our class, like so:

{color:#191918;}
bc. {color:#191918;}class JokeComponent {
  setup: string;
  punchline: string;
}pre

We are saying that this class has two properties,
bc. {color:#191918;}setup and
bc. {color:#191918;}punchline, both of them can only hold
bc. {color:#191918;}strings.

{background:none;}

The code
bc. {color:#191918;}:string is something called a type, and it’s a core part of TypeScript, something you probably are not used to if you’ve never worked with typed languages before.

We will discuss Types in more detail in the next section but in summary if we ever try to make these properties hold anything other than a string TypeScript will throw an error.

Classes

Remember I said that classes are blueprints for objects, or in other words instructions for how to create an object. To actually create an object using a
bc. {color:#191918;}class we use the
bc. {color:#191918;}new keyword, like so:

{color:#191918;}
bc. {color:#191918;}let joke = new JokeComponent()pre
{color:#191918;}joke is an object created using the
bc. {color:#191918;}JokeComponent class, another word for an object created using a class is a [_class instance_] or just [_instance_].

Since we have added some properties to the
bc. {color:#191918;}JokeComponent class the class instance that is created also has those properties.

{color:#191918;}
bc. {color:#191918;}console.log(joke.setup);
console.log(joke.punchline);pre

If we really did try to run the above code we would see that nothing gets printed out to the console, that’s because the
bc. {color:#191918;}setup and
bc. {color:#191918;}punchline properties have not been initialised, they are blank.

With classes how we initialise properties when we instantiate an object is via a special class function called a
bc. {color:#191918;}constructor.

{color:#191918;}
bc. {color:#191918;}class JokeComponent {
  setup: string;
  punchline: string;
constructor() { this.setup = “What did the cheese say when it looked in the mirror?”; this.punchline = “Halloumi (Hello Me)”; } }pre

Now when we instantiate the class the
bc. {color:#191918;}constructor function is called and this initialises the
bc. {color:#191918;}setup and
bc. {color:#191918;}punchline properties.

{background:none;}

In the interest of brevity I’m initialising our properties in the constructor, the recommended approach with initialising a component is to use Component Lifecycle Hooks, again more on that later.

String Interpolation

Currently the setup and punchline is hardcoded into the HTML template of our
bc. {color:#191918;}JokeComponent. We need to have the template output the contents of our properties instead.

We can do that in the template by using the special
bc. {color:#191918;}{{ }} syntax, also known as moustache syntax.

The
bc. {color:#191918;}{{ }} contains JavaScript which is run by Angular and the output inserted in the HTML.

So if we put
bc. {color:#191918;}{{ 1 + 1 }} in the template the number
bc. {color:#191918;}2 would be inserted into the HTML.

The template knows about the
bc. {color:#191918;}JokeComponent class it’s attached to so in-between the
bc. {color:#191918;}{{ }} we can also read properties or even call functions on our
bc. {color:#191918;}JokeComponent and have the output inserted in the HTML.

We just want to display the values of the
bc. {color:#191918;}setup and
bc. {color:#191918;}punchline properties so we just use those, like so:

{color:#191918;}
bc. {color:#191918;}<h1>{{setup}}</h1>
<p>{{punchline}}</p>pre

Summary

We’ve explained how a class is a blueprint for an object and we can create a specific instance of a class using the
bc. {color:#191918;}new keyword.

The class instance can have properties and we can bind those properties to portions of our template by using string interpolation via the
bc. {color:#191918;}{{ }} syntax.

Listing

http://plnkr.co/edit/AVR9vEtKvHD1AmvE2MTa?p=preview

Listing 1. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
  <link rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">




pre

Listing 2. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {NgModule}      from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Component} from '@angular/core';

@Component({ selector: ‘joke’, template: `

{{setup}}

{{punchline}}

`
})
class JokeComponent { setup: string; punchline: string;

constructor() { this.setup = “What did the cheese say when it looked in the mirror?”; this.punchline = “Halloumi (Hello Me)”; } }

@NgModule({ imports: [BrowserModule], declarations: [JokeComponent], bootstrap: [JokeComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

LOOPING

Our goal in this lecture is to display a list of jokes instead of just one.

{background:none;}

To add some visual jazz to our application we are going to be using the twitter bootstrap ui framework and specifically the card style for our
bc. {color:#191918;}JokeComponent.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    Using Arrays in TypeScript.
  • {color:#191918;}
    Using the
    bc. {color:#191918;}NgFor directive to repeat an element.

JokeListComponent

We will create a new component called
bc. {color:#191918;}JokeListComponent with the following listing:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-list',
  template: `
<div class="card card-block"
     *ngFor="let joke of jokes">
  <h4 class="card-title">{{joke.setup}}</h4>
  <p class="card-text">{{joke.punchline}}</p>
</div>
  `
})
class JokeListComponent {
  jokes: Object[];
constructor() { this.jokes = [ { setup: “What did the cheese say when it looked in the mirror?”, punchline: “Hello-Me (Halloumi)” }, { setup: “What kind of cheese do you use to disguise a small horse?”, punchline: “Mask-a-pony (Mascarpone)” }, { setup: “A kid threw a lump of cheddar at me”, punchline: “I thought ‘That’s not very mature’” }, ]; } }pre

Arrays

The first change you’ll notice is that we have a property called
bc. {color:#191918;}jokes and the type is
bc. {color:#191918;}Object[].

The
bc. {color:#191918;}[] syntax in the type means list of or Array, so the jokes property holds a list of
bc. {color:#191918;}Objects.

{background:none;}

Another perfectly legal way to write this would be
bc. {color:#191918;}Array but I prefer
bc. {color:#191918;}Object[] since for me it’s easier to see the
bc. {color:#191918;}[] characters at a glance.

In the constructor we initialise this array with some hilarious cheese jokes.

Card Element

You might notice in the template we are using some classes called
bc. {color:#191918;}card,
bc. {color:#191918;}card-block etc… this is from twitter bootstrap and it’s a style called a card which displays a rectangle with a border.

The basic HTML structure for a twitter bootstrap card element is like so:

{color:#191918;}
bc. {color:#191918;} <div class="card card-block">
  <h4 class="card-title"></h4>
  <p class="card-text"></p>
 </div>pre

NgFor

We want to repeat this card element for each joke in our array of jokes.

So we add a special syntax called an
bc. {color:#191918;}NgFor on the card element, like so:

{color:#191918;}
bc. {color:#191918;}<div class="card card-block"
     *ngFor="let joke of jokes">
  <h4 class="card-title"></h4>
  <p class="card-text"></p>
</div>pre
{color:#191918;}*ngFor="let joke of jokes" will create a new HTML element, using the div element it’s attached to as a template, for every joke in the jokes array.

It will also make available to the element a variable called
bc. {color:#191918;}joke which is he item in the joke array it’s currently looping over.

The syntax translates to
bc. {color:#191918;}let of 

{background:none;}

This is what we call in Angular a Directive. Specifically it’s a structural directive since it changes the structure of the DOM. We’ll be going through more built-in directives later on and also you’ll learn how to create your own.

So now we can display properties of this
bc. {color:#191918;}joke object in the HTML using
bc. {color:#191918;}{{joke.setup}} and
bc. {color:#191918;}{{joke.punchline}}, like so:

{color:#191918;}
bc. {color:#191918;}<div class="card card-block"
     *ngFor="let joke of jokes">
  <h4 class="card-title">{{joke.setup}}</h4>
  <p class="card-text">{{joke.punchline}}</p>
</div>pre

{background:none;}

If you’ve worked with Angular 1 before, you probably used the
bc. {color:#191918;}ng-repeat directive. NgFor is the analogous directive In Angular 2. Its syntax is slightly different but they have the same purpose.

Configuring

In order to use our
bc. {color:#191918;}JokeListComponent we need to add it to the declarations on our
bc. {color:#191918;}NgModule and also mark it as the component we want to bootstrap the page with.

{color:#191918;}
bc. {color:#191918;}
table<.
<.
 |<.
pre. {color:#191918;}1
2
3
4
5
pre
|<. pre. {color:#191918;}@NgModule({ imports:[BrowserModule], declarations: [JokeComponent, JokeListComponent], bootstrap: [JokeListComponent] })pre

|
pre

Since we are now bootstrapping
bc. {color:#191918;}JokeListComponent and it’s selector is
bc. {color:#191918;}joke-list we also need to change the root tag in our
bc. {color:#191918;}index.html, like so:

{color:#191918;}
bc. {color:#191918;}
table<.
<.
 |<.
pre. {color:#191918;}1
2
3
pre
|<. pre. {color:#191918;} pre

|
pre

{background:none;}

The classes
bc. {color:#191918;}container and
bc. {color:#191918;}m-t-1 are from twitter bootstrap and add some nice visual padding to the page.

Now if we run the application we see multiple jokes printed to the screen, like so:

Summary

When we declare an array in TypeScript we also tell it what Type of thing the array holds using
bc. {color:#191918;}Type[] or the
bc. {color:#191918;}Array syntax.

We can repeat the same element multiple times in Angular using the
bc. {color:#191918;}NgFor directive

Listing

http://plnkr.co/edit/6BGJzWKFuPLFeBdKZ6z2?p=preview

{background:none;}

Since we are now using the JokeListComponent as our root component, our root components tag has changed from
bc. {color:#191918;} to
bc. {color:#191918;}

Listing 1. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
  <link rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">




pre

Listing 2. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {NgModule}      from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Component} from '@angular/core';

@Component({ selector: ‘joke-list’, template: `

{{joke.setup}}

{{joke.punchline}}


`
})
class JokeListComponent { jokes: Object[];

constructor() { this.jokes = [ { setup: “What did the cheese say when it looked in the mirror?”, punchline: “Hello-Me (Halloumi)” }, { setup: “What kind of cheese do you use to disguise a small horse?”, punchline: “Mask-a-pony (Mascarpone)” }, { setup: “A kid threw a lump of cheddar at me”, punchline: “I thought ‘That’s not very mature’” }, ]; } }

@NgModule({ imports: [BrowserModule], declarations: [JokeListComponent], bootstrap: [JokeListComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

PROPERTY & EVENT BINDING

Our goal in this lecture is to hide the punchline of our jokes and only reveal them when the user clicks a button.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    How to use the hidden DOM property to hide/show elements.
  • {color:#191918;}
    Difference between DOM properties and HTML attributes.
  • {color:#191918;}
    How to perform input property binding with
    bc. {color:#191918;}[]
  • {color:#191918;}
    How to perform output event binding with
    bc. {color:#191918;}()

Hiding and showing elements

We can hide any element by adding an attribute called
bc. {color:#191918;}hidden to the element in HTML, so we could hide the punchline like so:

{color:#191918;}
bc. {color:#191918;}<p class="card-text" hidden>{{joke.punchline}}</p>pre

This is a core feature of HTML, not some functionality provided by Angular.

We want to add the
bc. {color:#191918;}hidden property to the element by default and then remove it when the user clicks a button.

So we add the following markup:

{color:#191918;}
bc. {color:#191918;}<p class="card-text" [hidden]="true">{{joke.punchline}}</p>pre

Specifically we added the markup
bc. {color:#191918;}[hidden]=“true“ and again it works, the element is hidden.

A few things:

{color:#191918;}

  1. {color:#191918;}
    We wrapped the attribute with a
    bc. {color:#191918;}[], more on that later.
  1. {color:#191918;}
    We made the attribute equal to
    bc. {color:#191918;}true, if we made it equal to
    bc. {color:#191918;}false it shows the element.

We say we have bound the value
bc. {color:#191918;}true to the property called
bc. {color:#191918;}hidden.

{background:none;}

This is called Input Property Binding and it’s a very important concept in Angular.

HTML Attribute vs DOM Property

The distinction between an HTML attribute and a DOM property is important in understanding binding in Angular.

HTML is a set of written instructions for how to display a web page.

The browser reads the HTML and creates something called a DOM, a Document Object Model. This is the manifestation of those HTML instructions in memory.

Changing the HTML doesn’t automatically update the webpage unless the user refreshes the browser, changing the DOM however instantly updates the webpage.

There is mostly a 1-to-1 mapping between the names and values of HTML attributes and their equivalent DOM properties, but not always.

The hidden HTML attribute is a good example, it only needs to
bc. {color:#191918;}exist on an HTML element to instruct the browser to hide the element.

So
bc. {color:#191918;}hidden=“true“ hides the element but confusingly so does
bc. {color:#191918;}hidden=“false“ in HTML we just need to add
bc. {color:#191918;}hidden to hide the element.

The DOM representation of the
bc. {color:#191918;}hidden attribute is a property also called
bc. {color:#191918;}hidden, which if set to
bc. {color:#191918;}true hides the element and
bc. {color:#191918;}false shows the element.

Angular doesn’t manipulate HTML attributes, it manipulates DOM properties because the DOM is what actually gets displayed.

So when we write
bc. {color:#191918;}[hidden] we are manipulating the DOM property and not the HTML attribute.

This is why the above is called Input Property Binding and not Input Attribute Binding.

Input Property Binding

Looking back at our use of the hidden property:

{color:#191918;}
bc. {color:#191918;}<p class="card-text" [hidden]="true">{{joke.punchline}}</p>pre

The target inside
bc. {color:#191918;}[] is the name of the property. In the example above the target is the
bc. {color:#191918;}hidden DOM property.

The text to the right of
bc. {color:#191918;}= is javascript code that gets executed and the resulting value is assigned to the target.

{background:none;}

{color:#191918;}true is still javascript code which if executed returns
bc. {color:#191918;}true.

So in summary, we are binding to the DOM property
bc. {color:#191918;}hidden and setting it to
bc. {color:#191918;}true so the element is hidden.

{background:none;}

In other parts of the web you’ll see this referred to as just property binding. However to distinguish it from the other type of binding in Angular I like to call this input property binding.

We can only use this type of binding to change the value of the target. We can’t use it to get notified when the target’s value changes, to do that we need to use something called Output Event Binding, more on that soon.

Let’s add a property called
bc. {color:#191918;}hide on each joke and set it to
bc. {color:#191918;}true, like so:

{color:#191918;}
bc. {color:#191918;}[
  {
    setup: "What did the cheese say when it looked in the mirror?",
    punchline: "Hello-Me (Halloumi)",
    hide: true
  },
  {
    setup: "What kind of cheese do you use to disguise a small horse?",
    punchline: "Mask-a-pony (Mascarpone)",
    hide: true
  },
  {
    setup: "A kid threw a lump of cheddar at me",
    punchline: "I thought ‘That’s not very mature’",
    hide: true
  },
]pre

Now we can set the hidden input property to
bc. {color:#191918;}joke.hide in the template, like so:

{color:#191918;}
bc. {color:#191918;}<div class="card card-block"
     *ngFor="let joke of jokes">
  <h4 class="card-title">{{joke.setup}}</h4>
  <p class="card-text"
     [hidden]="joke.hide">{{joke.punchline}}</p>
</div>pre

Output Event Binding

We want to show or hide the punchline when a user clicks a button, so lets add a button with the label Tell Me to the bottom of each card, like so:

{color:#191918;}
bc. {color:#191918;}<div class="card card-block"
     *ngFor="let joke of jokes">
  <h4 class="card-title">{{joke.setup}}</h4>
  <p class="card-text"
     [hidden]="joke.hide">{{joke.punchline}}</p>
  <a class="btn btn-primary">Tell Me</a>
</div>pre

We want to set
bc. {color:#191918;}joke.hide to
bc. {color:#191918;}false when the user clicks the button, and then back to
bc. {color:#191918;}true again when they click the button a second time.

To have Angular call some code every time someone clicks on the button we add some special markup to our button:

{color:#191918;}
bc. {color:#191918;}<a class="btn btn-primary"
   (click)="joke.hide = !joke.hide">Tell Me
</a>pre

We have some new syntax with
bc. {color:#191918;}(). The target inside the
bc. {color:#191918;}() is an event we want to listen for, we are listening for the click event.

The text to the right of
bc. {color:#191918;}= is some javascript which will be called every time a click event occurs.

{color:#191918;}joke.hide = !joke.hide toggles the value of
bc. {color:#191918;}joke.hide, so if it’s false clicking the button will change it to true, if it’s true clicking it will change it to false.

We can just as easily make the expression to the right of
bc. {color:#191918;}= call a function on our component instead, like so:

{color:#191918;}
bc. {color:#191918;}<a class="btn btn-primary"
   (click)="toggle(joke)">Tell Me
</a>pre

Now when the button gets clicked it calls the
bc. {color:#191918;}toggle(…​) function on the
bc. {color:#191918;}JokeListComponent and passes it the joke object the card is bound to, like so:

{color:#191918;}
bc. {color:#191918;}toggle(joke) {
  joke.hide = !joke.hide;
}pre

Now when we click the button, we set the show property to true which then unhides the element.

Summary

The way think about these two different ways of binding is in terms of inputs and outputs.

{color:#191918;}

  • {color:#191918;}
    With the
    bc. {color:#191918;}[] we are binding to an input of a Component.
  • {color:#191918;}
    With the
    bc. {color:#191918;}() we are binding to an output of a Component.

This is what we call one-way data binding, since data only flows one way, either into or out of a component.

It is possible to simulate two-way data binding in Angular and we’ll cover that in a later section on Forms.

Listing

http://plnkr.co/edit/6BGJzWKFuPLFeBdKZ6z2?p=preview

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {NgModule}      from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Component} from '@angular/core';

@Component({ selector: ‘joke-list’, template: `

{{joke.setup}}

{{joke.punchline}}


`
})
class JokeListComponent { jokes: Object[];

constructor() { this.jokes = [ { setup: “What did the cheese say when it looked in the mirror?”, punchline: “Hello-Me (Halloumi)” }, { setup: “What kind of cheese do you use to disguise a small horse?”, punchline: “Mask-a-pony (Mascarpone)” }, { setup: “A kid threw a lump of cheddar at me”, punchline: “I thought ‘That’s not very mature’” }, ]; } }

@NgModule({ imports: [BrowserModule], declarations: [JokeListComponent], bootstrap: [JokeListComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

DOMAIN MODEL

The goal of this lecture is to use a domain model to store our data instead of plain old objects.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    Why domain models are better for storing application state.
  • {color:#191918;}
    How to structure our application to use a domain model.

What are Domain Models?

A good practice when writing Angular code is to try to isolate the data structures you are using from the component code.

Right now our data structure is just an array of objects which we initialised on the component.

We also have this
bc. {color:#191918;}toggle function which doesn’t do anything other than modify a property of the object passed in, i.e. the function could exist outside of the component completely and still do it’s job just fine.

Imagine if this was a much larger application, if all the data was stored inside components as plain objects it would be hard for a new developer to find out where the data is stored and which function to edit.

To solve this, let’s create a class that represents a single joke and attach the toggle function to that class.

This class is what we call a Domain Model, it’s just a plain class which we will use to store data and functions.

Our Domain Model

We create a simple class with 3 properties, a constructor and a toggle function, like so:

{color:#191918;}
bc. {color:#191918;}class Joke {
  setup: string;
  punchline: string;
  hide: boolean;
constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }pre

As we’ve mentioned before we can instantiate a class by using the
bc. {color:#191918;}new keyword and when that happens javascript calls the
bc. {color:#191918;}constructor function where we can have code that initialises the properties.

However the constructors we’ve used so far have not had any arguments, the one for the joke class above does. It initialises the properties of the joke instance from the arguments passed into the constructor.

We can pass those arguments in when we instantiate a joke like so:

{color:#191918;}
bc. {color:#191918;}let joke = new Joke("What did the cheese say when it looked in the mirror?", "Hello-Me (Halloumi)");pre

We also added a toggle function which just flips the value of the
bc. {color:#191918;}hide property.

{background:none;}

We use
bc. {color:#191918;}this in a class function to distinguish between properties that are owned by the class instance vs. arguments that are passed in or declared locally by the function.

So
bc. {color:#191918;}this.joke in our toggle function is explicitly saying the
bc. {color:#191918;}joke property on the class instance.

Now lets change our
bc. {color:#191918;}JokeListComponent so it uses our domain model, like so:

{color:#191918;}
bc. {color:#191918;}class JokeListComponent {
  jokes: Joke[]; [_{color:#468C54;}①_]
constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror?”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse?”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } toggle(joke) { joke.hide = !joke.hide; } }pre

{color:#191918;}

  1. {color:#191918;} We changed the type of our
    bc. {color:#191918;}jokes property to
    bc. {color:#191918;}Joke[]. Now TypeScript will throw an error if we accidentally insert something other than an instance of a Joke class in this array.
  1. {color:#191918;} We also converted our
    bc. {color:#191918;}jokes array to now contain instance of the
    bc. {color:#191918;}Joke class instead of plain objects.

The final thing to do is to change the markup in the template so we call the
bc. {color:#191918;}joke.toggle() function on the joke instance and not the
bc. {color:#191918;}toggle(joke) function on the component, like so:

{color:#191918;}
bc. {color:#191918;}<a class="btn btn-warning" (click)="joke.toggle()">Tell Me</a>pre

Summary

Although its possible to store all your data as objects it’s both recommend and simple to encapsulate your data into domain models in Angular.

Using a domain model clarifies for all developers where you should put functions that need to act on the data, like our toggle function.

Listing

http://plnkr.co/edit/J0EoOCfhvLgNtLjigqy7?p=preview

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {NgModule}      from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Component} from '@angular/core';

class Joke { public setup: string; public punchline: string; public hide: boolean;

constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }

@Component({ selector: ‘joke-list’, template: `

{{joke.setup}}

{{joke.punchline}}

Tell Me
`
})
class JokeListComponent { jokes: Object[];

constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror?”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse?”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } }

@NgModule({ imports: [BrowserModule], declarations: [JokeListComponent], bootstrap: [JokeListComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

NESTING COMPONENTS & INPUTS

An application in Angular is a set of custom components glued together in HTML via inputs and outputs.

So far we’ve only built applications with a single component, our goal now is to start building applications that are composed of multiple components working together.

Breaking up an application into multiple logical components makes it easier to:

{color:#191918;}

  • {color:#191918;}
    Architect an application as it grows in complexity.
  • {color:#191918;}
    Re-use common components in multiple places.

The goal of this lecture is to break up our small application into 3 components and start gluing them together.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    How to create and configure multiple components in one application.
  • {color:#191918;}
    How to enable Input Property Binding on a custom component so components can communicate with each other.

Create & Configure Multiple Components

If you think of a typical webpage we can normally break it down into a set of logical components each with its own view, for example most webpages can be broken up into a header, footer and perhaps a sidebar.

We are going to break up our application into a root
bc. {color:#191918;}AppComponent, this component won’t have any functionality and will just contain other components.

This component will hold our
bc. {color:#191918;}JokeListComponent and our
bc. {color:#191918;}JokeListComponent will hold a list of
bc. {color:#191918;}JokeComponents.

{background:none;}

Most Angular apps will have a root component called AppRoot or AppComponent, this typically just acts as a container to hold other components.

Our components will therefore nest something like the below image:

{background:none;}

For the convenience of learning we are going to keep everything in one file. When building Angular apps the recommended approach is to have one component per file.

JokeComponent

This looks similar to our previous
bc. {color:#191918;}JokeListComponent we just removed the
bc. {color:#191918;}NgFor since this component will now render a single joke.

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke',
  template: `
<div class="card card-block">
  <h4 class="card-title">{{joke.setup}}</h4>
  <p class="card-text"
     [hidden]="joke.hide">{{joke.punchline}}</p>
  <a (click)="joke.toggle()"
     class="btn btn-warning">Tell Me
  </a>
</div>
  `
})
class JokeComponent {
  joke: Joke;
}pre

JokeListComponent

We’ve broken out a joke into its own
bc. {color:#191918;}JokeComponent so now we change the
bc. {color:#191918;}JokeListComponent template to contain multiple
bc. {color:#191918;}JokeComponent components instead.

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-list',
  template: `
<joke *ngFor="let j of jokes"></joke>
  `
})
class JokeListComponent {
  jokes: Joke[];
constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror?”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse?”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } }pre

AppComponent

Our final component is our new top level
bc. {color:#191918;}AppComponent, this just holds an instance of the
bc. {color:#191918;}JokeListComponent.

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'app',
  template: `
<joke-list></joke-list>
  `
})
class AppComponent {
}pre

Configuring multiple Components

In order to use our new components we need to add them to the declarations on our
bc. {color:#191918;}NgModule.

And since we’ve changed our top level component we need to set that in the bootstrap property as well as change our
bc. {color:#191918;}index.html to use the
bc. {color:#191918;} root component instead.

{color:#191918;}
bc. {color:#191918;}@NgModule({
  imports: [BrowserModule],
  declarations: [
    AppComponent,
    JokeComponent,
    JokeListComponent
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
}pre
{color:#191918;}
bc. {color:#191918;}<body class="container m-t-1">
  <app></app>
</body>pre

In Angular 2 we need to be explicit regarding what components & directives are going to use in our Angular Module by either adding them to the
bc. {color:#191918;}imports or
bc. {color:#191918;}declarations property.

In Angular 1 each directive when added via a script tag was globally available, which made it convenient for smaller projects but a problem for larger ones. Issues like name clashes came up often as different third party libraries often used the same names.

With Angular 2 two third party libraries can export the same name for components but only the version we explicitly include into our Angular Module will be used.

{background:none;}

The built-in directives we are using such as
bc. {color:#191918;}NgFor are all defined in
bc. {color:#191918;}CommonModule which is again included in
bc. {color:#191918;}BrowserModule which we have already added to our
bc. {color:#191918;}NgModule imports.

Input Property Binding on a Custom Component

If we ran the application now we would see just some empty boxes with some errors in the console, like so:

The errors should read something like:

{color:#191918;}
bc. {color:#191918;}class JokeComponent - inline template:2:25 caused by: Cannot read property 'setup' of undefinedpre

The above should give you a hint about what’s going on

{color:#191918;}

  1. {color:#191918;}
    It’s something to do with the
    bc. {color:#191918;}JokeComponent
  1. {color:#191918;}
    It’s something to do with the template.
  1. {color:#191918;}
    It’s something to do with the
    bc. {color:#191918;}setup property.

So if we look at the offending part of our
bc. {color:#191918;}JokeComponent template:

{color:#191918;}
bc. {color:#191918;}<h4 class="card-title">{{joke.setup}}</h4>pre

Essentially
bc. {color:#191918;}Cannot read property ‘setup’ of undefined in the context of
bc. {color:#191918;}joke.setup means that
bc. {color:#191918;}joke is undefined, it’s blank

If you remember from our
bc. {color:#191918;}JokeComponent class we do have a property called
bc. {color:#191918;}joke:

{color:#191918;}
bc. {color:#191918;}class JokeComponent {
  joke: Joke;
}pre

And we are looping and creating
bc. {color:#191918;}JokeComponents in our
bc. {color:#191918;}JokeListComponent, like so:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes"></joke>pre

But we are not setting the property
bc. {color:#191918;}joke of our
bc. {color:#191918;}JokeComponent to anything, which is why it’s
bc. {color:#191918;}undefined.

Ideally we want to write something like this:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes" [joke]="j"></joke>pre

In just the same way as we bound to the
bc. {color:#191918;}hidden property of the
bc. {color:#191918;}p tag in the element above we want to bind to the
bc. {color:#191918;}joke property of our
bc. {color:#191918;}JokeComponent.

Even though our
bc. {color:#191918;}JokeComponent has a
bc. {color:#191918;}joke property we can’t bind to it using the
bc. {color:#191918;}[] syntax, we need to explicitly mark it as an Input property on our
bc. {color:#191918;}JokeComponent.

We do this by pre-pending the
bc. {color:#191918;}joke property in the component with a new annotation called
bc. {color:#191918;}@Input, like so:

{color:#191918;}
bc. {color:#191918;}import { Input } from '@angular/core';
.
.
.
class JokeComponent {
  @Input() joke: Joke;
}pre

This tells Angular that the
bc. {color:#191918;}joke property is an input property and therefore in HTML we can bind to it using the
bc. {color:#191918;}[] input property binding syntax.

This
bc. {color:#191918;}@Input now becomes part of the public interface of our component.

Lets say at some future point we decided to change the
bc. {color:#191918;}joke property of our JokeComponent to perhaps just
bc. {color:#191918;}data, like so:

{color:#191918;}
bc. {color:#191918;}class JokeComponent {
  @Input() data: Joke;
}pre

Because this input is part of the public interface for our component we would also need to change all the input property bindings every where our component is used, like so:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes" [data]="j"></joke>pre

Not a great thing to ask the consumers of your component to have to do.

This is a common problem so to avoid expensive refactors the
bc. {color:#191918;}@Input annotation takes a parameter which is the name of the input property to the outside world, so if we changed our component like so:

{color:#191918;}
bc. {color:#191918;}class JokeComponent {
  @Input('joke') data: Joke;
}pre

To the outside world the input property name is still joke and we could keep the
bc. {color:#191918;}JokeListComponent template the same as before:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes" [joke]="j"></joke>pre

Summary

An Angular application should be broken down into small logical components which are glued together in HTML.

Its normal to have one root component called
bc. {color:#191918;}AppComponent which acts as the root node in the component tree.

We need to explicitly declare all components in the applications root
bc. {color:#191918;}NgModule.

We can make properties of our custom components input bindable with the
bc. {color:#191918;}[] syntax by pre-pending them with the
bc. {color:#191918;}@Input annotation.

Listing

http://plnkr.co/edit/LKj9OAoUMIUZhDS5HAiP?p=preview

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {NgModule, Input}      from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {Component} from '@angular/core';

class Joke { public setup: string; public punchline: string; public hide: boolean;

constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }

Component({ selector: 'joke', template: ` <div class="card card-block"> <h4 class="card-title">{{data.setup}}</h4> <p class="card-text" [hidden]="data.hide">{{data.punchline}}</p> <a (click)="data.toggle()" class="btn btn-warning">Tell Me </a> </div> ` }) class JokeComponent { Input(‘joke’) data: Joke;
}

@Component({ selector: ‘joke-list’, template: `
`
})
class JokeListComponent { jokes: Joke[];

constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror?”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse?”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } }

@Component({ selector: ‘app’, template: `
`
})
class AppComponent {
}

@NgModule({ imports: [BrowserModule], declarations: [ AppComponent, JokeComponent, JokeListComponent ], bootstrap: [AppComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

Listing 2. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
  <link rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">



pre

USER INTERACTION & OUTPUTS

In this lecture we are going to add an input form to our joke application so the user can add their own jokes to the list.

Learning Outcomes

{color:#191918;}

  • {color:#191918;}
    How to emit custom output events from components.
  • {color:#191918;}
    How to create local variables in the templates.

The Joke Form

We could add a form in our
bc. {color:#191918;}JokeListComponent it would definitely be easier to setup since all the code would be contained in one component.

However we are going create a new component to support the form, perhaps we want to re-use this form in other places in our application or perhaps we want this functionality in one component so it’s easier to test in isolation later on.

This component renders a bootstrap form on the page with two fields, setup and punchline, and a Create button.

When architecting an Angular application I often find it helps to first think about how your component is going to be used.

I believe our form component is best placed in the
bc. {color:#191918;}JokeListComponent template, like so:

{color:#191918;}
bc. {color:#191918;}<joke-form [_{color:#468C54;}①_]
  (jokeCreated)="addJoke($event)"> [_{color:#468C54;}②_]
</joke-form>
<joke *ngFor="let j of jokes" [joke]="j"></joke>pre

{color:#191918;}

  1. {color:#191918;} The components tag, its selector, is going to be
    bc. {color:#191918;}joke-form.
  1. {color:#191918;} The component is going to emit an event called
    bc. {color:#191918;}jokeCreated whenever a user clicks the Create button.

{background:none;}

We treat the component as a black-box, we don’t care how the component is implemented or how the user interacts with it. The parent component just wants to know when the user has created a new joke.

When the
bc. {color:#191918;}jokeCreated event is emitted I want to call the
bc. {color:#191918;}addJoke function.

{background:none;}

We’ll go through what
bc. {color:#191918;}$event means a bit later on in this chapter.

The above syntax describes the behaviour we expect from our
bc. {color:#191918;}JokeFormComponent, lets now go and create it.

The JokeFormComponent

The component renders a twitter bootstrap formatted form with two fields and a submit button, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-form',
  template: `
<div class="card card-block">
  <h4 class="card-title">Create Joke</h4>
  <div class="form-group">
    <input type="text"
           class="form-control"
           placeholder="Enter the setup">
  </div>
  <div class="form-group">
    <input type="text"
           class="form-control"
           placeholder="Enter the punchline">
  </div>
  <button type="button"
          class="btn btn-primary">Create
  </button>
</div>
  `
})
class JokeFormComponent {
}pre

{background:none;}

Remember to add
bc. {color:#191918;}JokeFormComponent to the declarations on the
bc. {color:#191918;}NgModule.

The component above just renders a form on the page, nothing happens when you click submit.

From the outside, all we care about this component is that it makes available an output event binding called
bc. {color:#191918;}jokeCreated.

To create a custom output event on our component we need to do two things:

{color:#191918;}

  1. {color:#191918;}
    Create an
    bc. {color:#191918;}EventEmitter property on the
    bc. {color:#191918;}JokeFormComponent class.
  1. {color:#191918;}
    Similar to when we created a custom input property binding, we need to annotate that property with the
    bc. {color:#191918;}@Output decorator.

{background:none;}

An
bc. {color:#191918;}EventEmitter is a helper class which we can use to emit events when something happens, other components can then bind and react to these events.

{color:#191918;}
bc. {color:#191918;}import {Output, EventEmitter} from '@angular/core';
.
.
.
class JokeFormComponent {
  @Output() jokeCreated = new EventEmitter<Joke>();
}pre

We have now created an output event property on the component.

{background:none;}

The name between the
bc. {color:#191918;}<> on the EventEmitter is the type of thing that will be output by this property. The syntax above is called
bc. {color:#191918;}generics and we’ll cover them in more detail on the section on TypeScript.

When the
bc. {color:#191918;}jokeCreated event fires we are going to pass out an instance of a
bc. {color:#191918;}Joke.

{background:none;}

We are initialising the property when it’s defined, in one line. Previously we just declared the properties and initialised them in a constructor.

The method you choose is up to you, with situations like this when the property will never need to change over time I like to initialise and declare on one line.

Lets now create a function called
bc. {color:#191918;}createJoke() and have it actually output an event, like so:

{color:#191918;}
bc. {color:#191918;}class JokeFormComponent {
  @Output() jokeCreated = new EventEmitter<Joke>();
createJoke() { this.jokeCreated.emit(new Joke(“A setup”, “A punchline”)); } }pre

We output an event by calling the
bc. {color:#191918;}emit function on our
bc. {color:#191918;}jokeCreated property. Whatever we pass to the
bc. {color:#191918;}emit function is what will be output by the property. We are outputting an instance of a Joke with some dummy data.

Gluing it all together

We need to call the
bc. {color:#191918;}createJoke function when the user clicks the Create button, like so:

{color:#191918;}
bc. {color:#191918;}<button type="button"
      class="btn btn-primary"
      (click)="createJoke()">Create
</button>pre

We also need to bind to the output event property on our parent
bc. {color:#191918;}JokeListComponent so we can add the joke that gets output to the list of jokes, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-list',
  template: `
<joke-form (jokeCreated)="addJoke($event)"></joke-form>
<joke *ngFor="let j of jokes" [joke]="j"></joke>
  `
})
class JokeListComponent {
  jokes: Joke[];
constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror?”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse?”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } addJoke(joke) { this.jokes.unshift(joke); } }pre

Breaking this down, in the template we bind to the jokeCreated property like so:

{color:#191918;}
bc. {color:#191918;}<joke-form (jokeCreated)="addJoke($event)"></joke-form>pre

This calls the
bc. {color:#191918;}addJoke function when the
bc. {color:#191918;}jokeCreated property outputs an event.

{background:none;}

{color:#191918;}$event is a special variable and holds whatever was emitted by the jokeCreated EventEmitter, in our case its an instance of a Joke.
{color:#191918;}
bc. {color:#191918;}addJoke(joke) {
  this.jokes.unshift(joke);
}pre

All the the addJoke function does is add the joke that got output to the front of the jokes array.

Angular automatically detects that the jokes array changed and then updated the view so it shows the new joke.

Now when we click the Create button we add the joke to the list, but it’s just showing the dummy fixed joke.

Template Reference Variables

So we’ve got the mechanism we are going to use to send events, how do we actually get the values from the input fields?

We want to actually get the value of the setup and punchline input fields and pass them to the
bc. {color:#191918;}createJoke function when the user clicks the Create button.

One way we can solve this problem in Angular is to use something called a template reference variable.

We add the string
bc. {color:#191918;}#setup to our setup input control, like so:

{color:#191918;}
bc. {color:#191918;}<input type="text"
       class="form-control"
       placeholder="Enter the setup"
       #setup>pre

This tells Angular to bind this
bc. {color:#191918;} control to the variable
bc. {color:#191918;}setup.

We can then use this variable
bc. {color:#191918;}setup in other places in the template.

{background:none;}

{color:#191918;}setup is only available as a variable in the template, we don’t automatically see the variable
bc. {color:#191918;}setup inside the javascript code of our
bc. {color:#191918;}JokeFormComponent class.
{color:#191918;}setup now points to the DOM element that represents an
bc. {color:#191918;}<input> control, which is an instance of the type
bc. {color:#191918;}HTMLInputElement.

Therefore to get the value of the setup input control we call
bc. {color:#191918;}setup.value.

We do the same to the other punchline input control, then we can pass both the setup and punchline values to the
bc. {color:#191918;}createJoke function, like so:

{color:#191918;}
bc. {color:#191918;}<button type="button"
      class="btn btn-primary"
      (click)="createJoke(setup.value, punchline.value)">Create
</button>pre

Finally we change the
bc. {color:#191918;}createJoke function so it accepts these new arguments and uses them to construct an instance of a Joke, like so:

{color:#191918;}
bc. {color:#191918;}createJoke(setup: string, punchline: string) {
  this.jokeCreated.emit(new Joke(setup, punchline));
}pre

Now when we run the application the user can add a new joke via the form and have it appear in the list below.

Summary

Similar to input properties, we can also create output properties on our custom components using the
bc. {color:#191918;}@Output annotation.

These output properties are always instances of the
bc. {color:#191918;}EventEmitter class and we output events by calling the
bc. {color:#191918;}emit function. Whatever we pass in to the
bc. {color:#191918;}emit function is output as the
bc. {color:#191918;}$event template variable.

We can create local template variables by adding variables starting with the
bc. {color:#191918;}# character on any element in our template.

By default that variable is only visible in the template that it’s declared in and points to the DOM element it’s attached to.

Listing

http://plnkr.co/edit/v3vmZkOK4fxDXsrziqHx?p=preview

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {Component, NgModule, Input, Output, EventEmitter} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

class Joke { public setup: string; public punchline: string; public hide: boolean;

constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }

Component({ selector: 'joke-form', template: ` <div class="card card-block"> <h4 class="card-title">Create Joke</h4> <div class="form-group"> <input type="text" class="form-control" placeholder="Enter the setup" #setup> </div> <div class="form-group"> <input type="text" class="form-control" placeholder="Enter the punchline" #punchline> </div> <button type="button" class="btn btn-primary" (click)="createJoke(setup.value, punchline.value)">Create </button> </div> ` }) class JokeFormComponent { Output() jokeCreated = new EventEmitter();

createJoke(setup: string, punchline: string) { this.jokeCreated.emit(new Joke(setup, punchline)); } }

Component({ selector: 'joke', template: ` <div class="card card-block"> <h4 class="card-title">{{data.setup}}</h4> <p class="card-text" [hidden]="data.hide">{{data.punchline}}</p> <a (click)="data.toggle()" class="btn btn-warning">Tell Me </a> </div> ` }) class JokeComponent { Input(‘joke’) data: Joke;
}

@Component({ selector: ‘joke-list’, template: `

`
})
class JokeListComponent { jokes: Joke[];

constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror?”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse?”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } addJoke(joke) { this.jokes.unshift(joke); } }

@Component({ selector: ‘app’, template: `
`
})
class AppComponent {
}

@NgModule({ imports: [BrowserModule], declarations: [ AppComponent, JokeComponent, JokeListComponent, JokeFormComponent ], bootstrap: [AppComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

Listing 2. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
  <link rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">



pre

WRAPPING UP

In this quick start section you created your first Angular Application!

You should now have at least a top level view of what an Angular 2 application is, how it functions and how to go about architecting it.

We covered:

{color:#191918;}
{color:#191918;}
Environment

{color:#191918;} How to use plnkr.co to write Angular 2 apps in a browser

{color:#191918;}
Components

{color:#191918;} Which let us extend the HTML language to create new tags and forms the basis of an Angular 2 application.

{color:#191918;}
Bootstrapping

{color:#191918;} How to actually make Angular load and take control of a HTML page.

{color:#191918;}
Binding

{color:#191918;} String interpolation with bc. {color:#191918;}{{ }} and both input property binding as well as output event binding.

{color:#191918;}
NgFor

{color:#191918;} How to render multiple elements using the the built-in bc. {color:#191918;}NgFor directive.

{color:#191918;}
Data Modelling

{color:#191918;} We touched on data modelling, by creating our own Joke class which encapsulated all our data and logic relate to a joke.

{color:#191918;}
Template Local Variables

{color:#191918;} Capturing user input from users by adding bc. {color:#191918;}# variables to input controls.

{color:#191918;}
Architecture

{color:#191918;} We started to see how we go about building Angular apps by wiring together inputs and outputs in order to glue Components together.

We’ll be going into much more detail into each of these topics, and others, in future chapters.

However since Angular 2 is based on TypeScript it makes sense to get a good understanding of those features before we dive into the rest of this course so that’s the topic of the next section.

ACTIVITY

Steps

Fork this plunker:

http://plnkr.co/edit/0iFNmdykDHKnRUMALM7K?p=preview

Extend the joke application in the above plunker so the user can delete a joke from the list.

Read any TODO comments in the plunker for hints.

Solution

When you are ready compare your answer to the solution in this plunker:

http://plnkr.co/edit/b0F6Dhb40Hm5zfiamAix?p=preview

TYPESCRIPT SETUP

Transpilation

Since browsers don’t know about TypeScript we need to convert our TypeScript code into something they do understand.

The current version of JavaScript with the broadest support across all browsers is still ES5, so that’s what we currently convert our TypeScript code into.

The process of converting TypeScript into ES5 is called transpilation and we use a tool called
bc. {color:#191918;}tsc to compile on the command line.

{background:none;}

It’s useful to have the
bc. {color:#191918;}tsc tool so you can try out TypeScript yourself and transpile on the command line but it’s not necessary to do this in your everyday Angular development.

Projects built using the Angular command line tools use the webpack bundler which handles transpilation of your TypeScript for you. When coding Angular via plunker SystemJS transpiles TypeScript for you in the browser.

It is good however to have
bc. {color:#191918;}tsc installed especially if you want quickly try our some TypeScript features and see how they are transpiled into ES5 or ES6.

Installing TypeScript

We can install typescript via
bc. {color:#191918;}npm

{color:#191918;}
bc. {color:#191918;}npm install -g typescriptpre

The preceding command will install the TypeScript compiler and add its executable
bc. {color:#191918;}tsc to your path.

To make sure everything worked correctly type:

{color:#191918;}
bc. {color:#191918;}tsc –vpre

And it should print something like

{color:#191918;}
bc. {color:#191918;}Version 1.8.0pre

Running TypeScript

Create a file called
bc. {color:#191918;}hello.ts.

Inside that file add
bc. {color:#191918;}console.log(‘hello world’);

We can compile a typescript file into a javascript file by calling:

{color:#191918;}
bc. {color:#191918;}tsc hello.tspre

This generates a file called
bc. {color:#191918;}hello.js

And we can execute that file by using node, like so:

{color:#191918;}
bc. {color:#191918;}node hello.jspre

We can watch a typescript file for changes and compile it automatically with:

{color:#191918;}
bc. {color:#191918;}tsc -w hello.tspre

We can provide configuration on the command line, like so:

{color:#191918;}
bc. {color:#191918;}tsc -t ES6 -w hello.tspre

{background:none;}

The above
bc. {color:#191918;}-t ES6 is a flag to tell typescript to transpile into ES6 instead of the default ES5.

However if we are want to watch a whole directory we need to use a configuration file.

We can create a config file with the most common settings like so:

{color:#191918;}
bc. {color:#191918;}tsc --initpre

If we want to watch all files in a directory we can just type:

{color:#191918;}
bc. {color:#191918;}tsc -wpre

{background:none;}

If there are errors, by default TypeScript will still output the javascript file if it can, this behaviour can be changed in the config.

OVERVIEW

TypeScript is an open source programming language that is developed and maintained by Microsoft.

It was initially released in 2012.

TypeScript is a super-set of ES6.

That means whatever features we have in ES6 are also in TypeScript with some extra features on top, such as static typing and richer syntax.

In this section will cover both; we will go over some of the key features of ES6 and then we will cover some of the key features of TypeScript.

ES6 Support

ES6 is an agreement for how JavaScript should function in the future.

Its up to each browser manufacturer to implement those features according to that agreement.

Therefore all browsers don’t support all the features of ES6 yet.

Chrome has the best support by far and so does Node. I will be providing plunkers where you can try out the code yourself, remember to use Chrome to run the plunker.

Sometimes ES6 features are only switched on when we are in “use strict” mode, so to test our ES6 code my recommendation is to always add “use strict” to the top of your files.

A list of all the ES6 features and current support across a variety of platforms can be found here: http://kangax.github.io/compat-table/es6/

{background:none;}

We should be using at least node version 6 to support most of the ES6 features we will be demonstrating in this section.

TypeScript Support

TypeScript transpiles down into ES5 so we don’t need to worry about browser support.

Code will be provided for all the examples, but also we’ll explain how to how to compile typescript locally on your computer with the command line tools.

LET

Block Scope

A confusing point for developers coming from different languages is the way variable scope behaves in JavaScript.

{background:none;}

Scope refers to the lifecycle of a variable, i.e. where in the code it’s visible and for how long.

In Java and C++ there is the concept of block scope, a block is any code that is wrapped in
bc. {color:#191918;}{ and
bc. {color:#191918;}}, like so:

{color:#191918;}
bc. {color:#191918;}{
    // This is a block
}
// This is not part a blockpre

This means that in those languages if you declare a variable inside a block, it’s only visible inside that block and any nested blocks inside that block.

But in ES5 JavaScript we only have two scopes, the global scope and function scope.

So if I wrote:

{color:#191918;}
bc. {color:#191918;}{
  var a = "block";
}
console.log(a);pre

Those coming from Java or C++ backgrounds might think that this would throw an error because we are trying to use the variable
bc. {color:#191918;}a outside of the block it was created in. But in JavaScript it doesn’t, this code is perfectly legal.

The variable
bc. {color:#191918;}a, as we’ve declared it above, exists in global scope so this means it’s visible from everywhere in our application.

In ES5 apart from global scope, the only other scope is function scope, so if we wrote.

{color:#191918;}
bc. {color:#191918;}function hello() {
    var a = "function";
}
hello();
console.log(a);pre

If we ran the above we would get an error, like so:

{color:#191918;}
bc. {color:#191918;}Uncaught ReferenceError: a is not defined(…)pre

This is because the
bc. {color:#191918;}a variable is declared inside a function and is therefore only visible inside that function, trying to access it outside the function results in an error.

But again this isn’t block level scope as we can see if we add a for loop inside the function, like so:

{color:#191918;}
bc. {color:#191918;}function hello() {
    var a = "function";
    for (var i = 0; i < 10; i++) {
        var a = "block";
    }
    console.log(a);
}
hello();pre

What gets printed out here is
bc. {color:#191918;}block not
bc. {color:#191918;}function despite the fact we are outside the for loop, that’s because the body of the for loop is not its own scope.

IIFE

This issue of no block level scope has plagued JavaScript developers since its inception.

One common workaround in the past has been to use something called an Immediately Invoked Function Expression (IIFE) like so:

{color:#191918;}
bc. {color:#191918;}function hello() {
    var a = "function";
for (var i=0; i<5; i++) { (function() { var a = “block”; })(); } console.log(a); } hello();pre

This now prints out
bc. {color:#191918;}function.

If this syntax looks a bit strange to you:

{color:#191918;}
bc. {color:#191918;}(function() {
    var a = "block";
})();pre

Know its just a shorter way of writing:

{color:#191918;}
bc. {color:#191918;}function something() {
  var a = "block";
}
something();pre

It’s a function that we call immediately after defining it.

Since functions have their own scope, using an IIFE has the same effect as if we had block level scope, the variable
bc. {color:#191918;}a inside the IIFE isn’t visible outside the IIFE.

Let

IIFEs work but it’s a pretty long winded way of solving this problem. So with ES6 we now have the new
bc. {color:#191918;}let keyword, we use it in place of the
bc. {color:#191918;}var keyword and it creates a variable with block level scope, like so:

{color:#191918;}
bc. {color:#191918;}function hello() {
    var a = "function";
    for (var i = 0; i < 5; i++) {
        let a = "block";
    }
    console.log(a);
}
hello();pre

Now the
bc. {color:#191918;}a declared in the for loop body only exists between the
bc. {color:#191918;}{ and
bc. {color:#191918;}}, and the code snippet above prints out
bc. {color:#191918;}function as expected.

Using let in for loops

So a classic interview question to test JavaScript developers knowledge of the lack of block level scope is this one:

{color:#191918;}
bc. {color:#191918;}var funcs = [];
for (var i = 0; i < 5; i += 1) {
    var y = i;
    funcs.push(function () {
        console.log(y);
    })
}
funcs.forEach(function (func) {
    func()
});pre

What gets printed out?

You might expect

{color:#191918;}
bc. {color:#191918;}0
1
2
3
4pre

But in fact it’s

{color:#191918;}
bc. {color:#191918;}5
5
5
5
5pre

The reason for this is that the variable
bc. {color:#191918;}y is not block level, it doesn’t only exist inside its enclosing
bc. {color:#191918;}{}
In fact it’s a global variable and by the time any of the functions are called it’s already been set to 5.

In the above example if we replace
bc. {color:#191918;}var y = i with
bc. {color:#191918;}let y = i then the variable
bc. {color:#191918;}y only exists inside it’s block, like so:

{color:#191918;}
bc. {color:#191918;}var funcs = [];
for (var i = 0; i < 5; i += 1) {
    let y = i;
    funcs.push(function () {
        console.log(y);
    })
}
funcs.forEach(function (func) {
    func()
});pre

And so executing this now results in:

{color:#191918;}
bc. {color:#191918;}0
1
2
3
4pre

The for loop short-cut

The above construct is so common we have a shortcut, we can declare the index variable
bc. {color:#191918;}i with
bc. {color:#191918;}let in the for loop expression, like so:

{color:#191918;}
bc. {color:#191918;}var funcs = [];
for (let i = 0; i < 5; i += 1) {
    funcs.push(function () {
        console.log(i);
    })
}
funcs.forEach(function (func) {
    func()
});pre

Even though
bc. {color:#191918;}let i = 0 is strictly declared outside of the for block
bc. {color:#191918;}{ }, any variables declared in the for loop expression with
bc. {color:#191918;}let has block level scope in the for loop.

Summary

{color:#191918;}let is a very important addition the javascript language in ES6.

It’s not a replacement to
bc. {color:#191918;}var,
bc. {color:#191918;}var can still be used even in ES6 and has the same semantics as ES5.

However unless you have a specific reason to use
bc. {color:#191918;}var I would expect all variables you define from now on to use
bc. {color:#191918;}let.

Listing

http://plnkr.co/edit/k7150PqX1DML7EFHKuRc?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}/* let */
var funcs = [];
for (let i = 0; i < 5; i += 1) {
  funcs.push(function () {
    console.log(i);
  })
}
funcs.forEach(function (func) {
  func()
});pre

Listing 2. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<html>
<head>
  <script src="script.js"></script>
</head>
</html>pre

CONST

{color:#191918;}const is a new keyword which declares a variable as [_constant over time_].

Declaring a const variable

We can use
bc. {color:#191918;}const to declare a variable but unlike
bc. {color:#191918;}let and
bc. {color:#191918;}var it must be immediately initialised, with a value that can’t be changed afterwards.

If we try to declare it without initialising it we get a
bc. {color:#191918;}SyntaxError, like so:

{color:#191918;}
bc. {color:#191918;}const foo; // SyntaxError: Missing initializer in const declarationpre

If we try to change it after we have declared and initialised it we get a
bc. {color:#191918;}TypeError, like so:

{color:#191918;}
bc. {color:#191918;}const foo = 1;
foo = 2; // TypeError: Assignment to constant variablepre

Block scoping

Both
bc. {color:#191918;}let and
bc. {color:#191918;}const create variables that are block-scoped – they only exist within the innermost block that surrounds them.

{color:#191918;}
bc. {color:#191918;}function func() {
    if (true) {
        const tmp = 123;
    }
    console.log(tmp); // Uncaught ReferenceError: tmp is not defined
}
func();pre

Immutable variable

Variables created by
bc. {color:#191918;}let and
bc. {color:#191918;}var are mutable:

{color:#191918;}
bc. {color:#191918;}let foo = "foo";
foo = "moo";
console.log(foo);pre

{background:none;}

Mutable in this case means can change over time.

Variables created by
bc. {color:#191918;}const however are immutable, they don’t change over time, specifically the the const variable can’t point to another thing later on.

{color:#191918;}
bc. {color:#191918;}const foo = 'abc';
foo = 'def'; // TypeError: Assignment to constant variablepre

Mutable Value

There is one big pitfall with
bc. {color:#191918;}const however.

When we say “`const` variables are immutable” it only means that the variable always has to point to the same thing. It does not mean than the thing it points to can’t change over time.

For example, if the variable
bc. {color:#191918;}foo is a
bc. {color:#191918;}const that points to an object – we can’t make
bc. {color:#191918;}foo point to another object later on:

{color:#191918;}
bc. {color:#191918;}const foo = {};
foo = {}; // TypeError: Assignment to constant variable.pre

But we can however mutate, make changes to, the object
bc. {color:#191918;}foo points to, like so:

{color:#191918;}
bc. {color:#191918;}const foo = {};
foo['prop'] = "Moo"; // This works!
console.log(foo);pre

If we want the value of
bc. {color:#191918;}foo to be immutable we have to freeze it using
bc. {color:#191918;}Object.freeze(…​).

When we freeze an object we can’t change it, we can’t add properties or change the values of properties, like so:

{color:#191918;}
bc. {color:#191918;}const foo = Object.freeze({});
foo.prop = 123;
console.log(foo.prop) // undefinedpre

However by default the above doesn’t throw an error, it just silently ignores the issue. So in the example above it didn’t throw an error when we tried to set
bc. {color:#191918;}foo.prop = 123 but when we try to print out the value on the next line we just get
bc. {color:#191918;}undefined.

To force
bc. {color:#191918;}Object.freeze(…​) to throw an error we must remember to be in
bc. {color:#191918;}“use strict“ mode, like so:

{color:#191918;}
bc. {color:#191918;}"use strict";
const foo = Object.freeze({});
foo.prop = 123; // SyntaxError: Identifier 'foo' has already been declaredpre

Summary

{color:#191918;}const lets us declare variables which don’t change over time, which are immutable.

The important gotcha with const is that the variable is immutable, but not the value, the thing the variable points to.

This means that if we declare an object as
bc. {color:#191918;}const, confusingly we can still change properties of the object later on.

To solve this and make an object immutable we use the
bc. {color:#191918;}Object.freeze(…​) function which together with the
bc. {color:#191918;}“use strict”; param throws an error if we try to change the object.

Listing

http://plnkr.co/edit/aonRA66o6xAzRHUzbrYM?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}'use strict';

/* // Declaring a const variable
const foo; // SyntaxError: Missing initializer in const declaration
*/

/* // Declaring a const variable
const moo = 1;
moo = 2; // TypeError: `foo` is read-only
*/

/* // Block Scoping
function func() { if (true) { const tmp = 123; } console.log(tmp); // Uncaught ReferenceError: tmp is not defined
}
func();
*/

const foo = Object.freeze({});
foo.prop = 1;
console.log(foo.prop);pre

Listing 2. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<html>
<head>
  <script src="script.js"></script>
</head>
</html>pre

TEMPLATE STRINGS

Multi-Line Strings

With ES5 and ES6 we can specify a string with either the
bc. {color:#191918;}‘ or
bc. {color:#191918;}“ characters.

{color:#191918;}
bc. {color:#191918;}let single = "hello world";pre

But in ES5 if we wanted to make that string span multiple lines it quickly becomes a pain.

{color:#191918;}
bc. {color:#191918;}let single = 'hello ' +
    'world ' +
    'my ' +
    'name ' +
    'is ' +
    'asim';pre

If we wanted each line in the string to contain new line characters, matching how it was written, we had to remember to add
bc. {color:#191918;}\n to the end of each string.

{color:#191918;}
bc. {color:#191918;}let single = 'hello\n' +
    'world\n' +
    'my\n' +
    'name\n' +
    'is\n' +
    'asim\n';pre

In ES6 we have another way of defining strings, using the back-tick character
bc. {color:#191918;}`

{color:#191918;}
bc. {color:#191918;}let multi = `
hello
world
my
name
is
asim`;
console.log(multi);pre

The above prints out:

{color:#191918;}
bc. {color:#191918;}hello
world
my
name
is
asimpre

With
bc. {color:#191918;}` strings can now span multiple lines and they are also formatted with new line characters.

Variable Substitution

Another really interesting feature of declaring strings with
bc. {color:#191918;}` is that they can now expand variables using the
bc. {color:#191918;}${variable_name} syntax, like so:

{color:#191918;}
bc. {color:#191918;}let name = "asim";

let multi = `
hello
world
my
name
is
${name}
`;
console.log(multi);pre

prints out:

{color:#191918;}
bc. {color:#191918;}hello
world
my
name
is
asimpre

Summary

Template strings are a small change to JavaScript in ES6 but the convenience of multi-line strings and variable substitution is substantial.

Listing

http://plnkr.co/edit/Io5rE4kUBp1xQgAphuih?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}'use strict';

let name = “Asim”;

let multi = `hello
world
my
name
is
${name}`;
console.log(multi);pre

FAT ARROW FUNCTIONS

Syntax

JavaScript has first class functions.

This means that in JavaScript functions can be themselves be passed around like any other value, even as arguments to other functions.

E.g. we can pass to the
bc. {color:#191918;}setTimeout function, a function, like so:

{color:#191918;}
bc. {color:#191918;}setTimeout(function() {
        console.log("setTimeout called!");
}, 1000);pre

The function we pass as an argument to
bc. {color:#191918;}setTimeout is called an anonymous function because it doesn’t have a name.

ES6 has introduced a slightly different syntax to define anonymous functions called the fat arrow syntax, with it we can re-write the above as:

{color:#191918;}
bc. {color:#191918;}setTimeout(() => {
    console.log("setTimeout called!")
}, 1000);pre

If the function only contains one expression we can drop the braces and shorten even further to:

{color:#191918;}
bc. {color:#191918;}setTimeout(() => console.log("setTimeout called!"), 1000);pre

Arguments

What if we wanted to pass an argument to the function?

We can re-write the below normal function to one that uses the fat arrow syntax:

{color:#191918;}
bc. {color:#191918;}let add = function(a,b) {
        return a + b;
};pre

Can now be written as:

{color:#191918;}
bc. {color:#191918;}let add = (a,b) => a + b;pre

{background:none;}

In the first example we write
bc. {color:#191918;}return a + b but in the fat arrow version we just wrote
bc. {color:#191918;}a + b. That’s because in the fat arrow syntax if it is on one line, the statement gets returned automatically without the need to use the
bc. {color:#191918;}return keyword.

this

Lets imagine we have an
bc. {color:#191918;}object with a function called
bc. {color:#191918;}sayLater, like so:

{color:#191918;}
bc. {color:#191918;}let obj = {
        name: "asim",
        sayLater: function() {
                console.log(`${this.name}`);
        }
};
obj.sayLater();pre

In the
bc. {color:#191918;}sayLater function
bc. {color:#191918;}this points to
bc. {color:#191918;}obj

So
bc. {color:#191918;}console.log(${this.name}`);` prints out
bc. {color:#191918;}asim.

Now lets imagine that we log the message using the
bc. {color:#191918;}setTimeout function.

{color:#191918;}
bc. {color:#191918;}let obj = {
    name: "asim",
    sayLater: function () {
        setTimeout(function () {
            console.log(`${this.name}`);
        }, 1000);
    }
};
obj.sayLater();pre

In the
bc. {color:#191918;}sayLater() function we call
bc. {color:#191918;}setTimeout and then log the value of
bc. {color:#191918;}this.name, which we expect to be asim.

In fact we get
bc. {color:#191918;}undefined printed out to the console.

Calling context

The reason for this is that the value of
bc. {color:#191918;}this in a function depends on how the function is called.

At it’s most basic level if the function is called as
bc. {color:#191918;}obj.sayLater(), the value of
bc. {color:#191918;}this is the calling context which in this case is
bc. {color:#191918;}obj.

What is the calling context for the anonymous function we pass to
bc. {color:#191918;}setTimeout? What will
bc. {color:#191918;}this point to inside that function?

{color:#191918;}
bc. {color:#191918;}setTimeout(function () {
    console.log(`${this.name}`);
}, 1000);pre

The answer is it depends.

In the browser it’s either
bc. {color:#191918;}undefined or the
bc. {color:#191918;}global object depending on if you are running in strict mode or not. In node it’s an internal
bc. {color:#191918;}timeout object.

In all cases however it isn’t going to be
bc. {color:#191918;}obj, so
bc. {color:#191918;}this.name is not going to return asim, it’s going to return
bc. {color:#191918;}undefined or raise an error.

This instability of
bc. {color:#191918;}this is an incredibly common problem in javascript that has affected it since the early days.

In ES5 there are a number of methods we can use to stabilise the value of
bc. {color:#191918;}this. One common solution is to assign
bc. {color:#191918;}this to another variable at the top, usually called
bc. {color:#191918;}self or
bc. {color:#191918;}vm, and then always use
bc. {color:#191918;}self in the function body, like so:

{color:#191918;}
bc. {color:#191918;}let obj = {
    name: "asim",
    sayLater: function () {
        let self = this; // Assign to self
        console.log(self);
        setTimeout(function () {
            console.log(`${self.name}`); // Use self not this
        }, 1000);
    }
};pre

But in ES6 we can do better, if we use fat arrow functions the value of
bc. {color:#191918;}this inside a fat arrow function will be the same as the value of
bc. {color:#191918;}this outside the fat arrow function.

It uses the value of
bc. {color:#191918;}this from the surrounding code for its context. i.e. whatever
bc. {color:#191918;}this points to in the surrounding code,
bc. {color:#191918;}this will point to in the function body of the fat arrow function.

We can re-write our obj to use fat arrow syntax like so:

{color:#191918;}
bc. {color:#191918;}let obj = {
    name: "asim",
    sayLater: function () {
        console.log(this); // `this` points to obj
        setTimeout(() => {
            console.log(this); // `this` points to obj
            console.log(`${this.name}`); // `this` points to obj
        }, 1000);
    }
};
obj.sayLater();pre

If we ran the above code we would see that the value of
bc. {color:#191918;}this in the
bc. {color:#191918;}setTimout function is now
bc. {color:#191918;}obj; the same as the value of
bc. {color:#191918;}this outside the
bc. {color:#191918;}setTimeout function.

Summary

The new fat arrow function syntax in ES6 is far more than just a slightly shorter way of writing anonymous functions.

It has finally solved the thorny issue of stabilising the value of
bc. {color:#191918;}this that has affected javascript since the start and caused so many work arounds to be discussed and applied in code.

Listing

http://plnkr.co/edit/nrRHlewsnCjZxnkYUS4q?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}'use strict';

setTimeout(() => { console.log(“setTimeout called!”)
}, 1000);

setTimeout(() => console.log(“setTimeout called!”), 1000);

let add = (a,b) => a + b;
console.log(add(1,2));

let obj = { name: “Asim”, sayLater: function() { setTimeout(() => console.log(`${this.name}`), 1000) }
};
obj.sayLater();pre

DESTRUCTURING

Destructuring is a way of extracting values into variables from data stored in objects and arrays.

Object Destructuring

Let’s imagine we have an object like so:

{color:#191918;}
bc. {color:#191918;}const obj = {first: 'Asim', last: 'Hussain', age: 39 };pre

We want to extract the
bc. {color:#191918;}first and
bc. {color:#191918;}last properties into local variables, prior to ES6 we would have to write something like this:

{color:#191918;}
bc. {color:#191918;}const f = obj.first;
const l = obj.last;
console.log(f); // Asim
console.log(l); // Hussainpre

With destructing we can do so in one line, like so:

{color:#191918;}
bc. {color:#191918;}const {first: f, last: l} = obj;
console.log(f); // Asim
console.log(l); // Hussainpre
{color:#191918;}{first: f, last: l} describes a [_pattern_], a set of rules for [_how_] we want to destructure an object.

{background:none;}

{color:#191918;}const {first: f}  = obj; translates to [_extract the property
bc. {color:#191918;}first and store in a constant called f_].

If we wanted to extract the properties into variables with the same name we would write it like so:

{color:#191918;}
bc. {color:#191918;}const {first: first, last: last} = obj;
console.log(first); // Asim
console.log(last); // Hussainpre

The above is quite a common use case for destructuring so it has a shortcut, like so

{color:#191918;}
bc. {color:#191918;}// {prop} is short for {prop: prop}
const {first, last} = obj;
console.log(first); // Asim
console.log(last); // Hussainpre

Array Destructuring

Array destructuring works in a similar way except it extracts based of the index in the array, like so:

{color:#191918;}
bc. {color:#191918;}const arr = ['a', 'b'];
const [x, y] = arr;
console.log(x); // a
console.log(y); // bpre

Function Parameter Destructuring

One really useful use case for destructuring is in function parameters.

Typically if we want to pass multiple params to a function, with maybe some optional parameters, we would pass it in as an object like so:

{color:#191918;}
bc. {color:#191918;}function f(options) {
  console.log(options.x);
}
f({x:1}); // 1pre

Now we can define the function parameter list as an object destructure pattern, like so:

{color:#191918;}
bc. {color:#191918;}function f({x}) {
  console.log(x); // Refer to x directly
}
f({x:1});pre

Notice that in the function body above we can refer to
bc. {color:#191918;}x directly, we don’t have to refer to it through an object property like
bc. {color:#191918;}options.x.

In addition to that when using destructured function parameters we can also provide default values, like so:

{color:#191918;}
bc. {color:#191918;}function f({x=0}) {
  console.log(x);
}
f({}); // 0pre

In the above example
bc. {color:#191918;}x now has a default value of 0 even if it’s not passed into the function when called.

Summary

Destructuring is a useful feature of ES6, with it we can extract values from objects and arrays with ease.

Through function parameter destructing we now have a built in syntax for providing optional parameters to functions, including giving them default values if none are provided.

Listing

http://plnkr.co/edit/v6BS0PekPcDZN0QpV8wN?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}'use strict';

// Object Destructuring
const obj = {first: ‘Asim’, last: ‘Hussain’, age: 39};

function getObj() { return obj;
}

const {first, last} = getObj();

console.log(first);
console.log(last);

// Array Destructuring
const arr = [‘a’, ‘b’];
const [x, y] = arr;
console.log(x);
console.log(y);

// Function Parameter Destructuring
function func({x = 1}) { console.log(x);
}
func({});pre

FOR OF

In this lecture we are going to examine how we can loop over arrays, using the methods available to us in the past with ES5 and also the new
bc. {color:#191918;}for-of looping mechanism in ES6.

For & ForEach

We have a couple of ways of looping through Arrays in ES5 javascript.

For one we have the classic
bc. {color:#191918;}for loop, like so:

{color:#191918;}
bc. {color:#191918;}let array = [1,2,3];
for (let i = 0; i < array.length; i++) {
  console.log(array[i]);
}pre

With ES5 JavaScript we can also use the
bc. {color:#191918;}forEach method on the Array class, like so:

{color:#191918;}
bc. {color:#191918;}let array = [1,2,3];
array.forEach(function (value) {
  console.log(value);
});
// 1
// 2
// 3pre

It’s slightly shorter but has a few downsides:

{color:#191918;}

  1. {color:#191918;}
    You can’t break out of this loop using a
    bc. {color:#191918;}break statement or move to the next iteration with
    bc. {color:#191918;}continue.
  1. {color:#191918;}
    You can’t return from the enclosing function using a
    bc. {color:#191918;}return statement.

For In

The
bc. {color:#191918;}for-in loop is designed for iterating over an objects properties, like so:

{color:#191918;}
bc. {color:#191918;}var obj = {a:1,b:2};
for (let prop in obj) {
    console.log(prop);
}
// a
// bpre

If we tried to use it with an array, it might initially look like it’s working:

{color:#191918;}
bc. {color:#191918;}let array = [10,20,30];
for (let index in array) {
  console.log(index);
});
// 0
// 1
// 2pre

But if we tried to print out the type of
bc. {color:#191918;}index like so:

{color:#191918;}
bc. {color:#191918;}let array = [10,20,30];
for (let index in array) {
  console.log(typeof(index));
};
// string
// string
// stringpre

The
bc. {color:#191918;}index variable is a string and not a number, using
bc. {color:#191918;}for-in with arrays converts the index to a string.

{background:none;}

If you are expecting a number but in fact have a string this can cause problems, for example
bc. {color:#191918;}“1” + “2“ is the string
bc. {color:#191918;}“12“ and not the number
bc. {color:#191918;}3.

For-of loop

Rather than change the way the
bc. {color:#191918;}for-in loops work in ES6 and in the process create a breaking change, instead in ES6 we have a new syntax called
bc. {color:#191918;}for-of.

{color:#191918;}
bc. {color:#191918;}let array = [10,20,30];
for (var value of array) {
  console.log(value);
}
// 10
// 20
// 30pre

{color:#191918;}

  • {color:#191918;}
    This is the most concise way of looping through array elements.
  • {color:#191918;}
    It avoids all the pitfalls of
    bc. {color:#191918;}for–in.
  • {color:#191918;}
    It works with
    bc. {color:#191918;}break,
    bc. {color:#191918;}continue, and
    bc. {color:#191918;}return

Summary

The
bc. {color:#191918;}for–in loop is for looping over object properties.

The
bc. {color:#191918;}for–of loop is for looping over the values in an array.

{color:#191918;}for–of is not just for arrays. It also works on most array-like objects including the new
bc. {color:#191918;}Set and
bc. {color:#191918;}Map types which we will cover in the next lecture.

Listing

http://plnkr.co/edit/v6BS0PekPcDZN0QpV8wN?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}'use strict';

// Object Destructuring
const obj = {first: ‘Asim’, last: ‘Hussain’, age: 39};

function getObj() { return obj;
}

const {first, last} = getObj();

console.log(first);
console.log(last);

// Array Destructuring
const arr = [‘a’, ‘b’];
const [x, y] = arr;
console.log(x);
console.log(y);

// Function Parameter Destructuring
function func({x = 1}) { console.log(x);
}
func({});pre

MAP & SET

Using Object as a Map

In ES5 and below the only data structure we had to map keys to values was an
bc. {color:#191918;}Object, like so:

{color:#191918;}
bc. {color:#191918;}let obj = {key: "value", a: 1}
console.log(obj.a); // 1
console.log(obj['key']); // "value"pre

However it does have a few pitfalls.

Inherited Objects

Looping over objects with
bc. {color:#191918;}for-in also iterated over the inherited properties as well as the objects own properties, like so:

{color:#191918;}
bc. {color:#191918;}let base = {a:1,b:2};
let obj = Object.create(base);
obj[c] = 3;
for (prop in obj) console.log(prop)
// a
// b
// cpre

{background:none;}

{color:#191918;}Object.create creates a new objects who’s [_prototype_] points to the passed in
bc. {color:#191918;}base object. If it can’t find a requested property on
bc. {color:#191918;}obj, javascript then tries to search the
bc. {color:#191918;}base object for the same property.

Perhaps this is the behaviour you want? Or perhaps you only want to print out the keys that belong to the current object?

With ES5 JavaScript to ensure you were looking at a property of the current object we need to use the
bc. {color:#191918;}hasOwnProperty function, like so:

{color:#191918;}
bc. {color:#191918;}let base = {a:1,b:2};
let obj = Object.create(base);
obj[c] = 3;
for (prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        console.log(prop)
    }
}
// cpre

Overriding Functions

If we are using Object as a dictionary then we could theoretically store a key of
bc. {color:#191918;}hasOwnProperty which then leads to the code in the example above failing, like so:

{color:#191918;}
bc. {color:#191918;}let obj = {hasOwnProperty: 1};
obj.hasOwnProperty("test");
// TypeError: Property 'hasOwnProperty' is not a functionpre

h4<{color:#4F4F4C;}.
bc. {color:#4F4F4C;}proto property

{color:#191918;}[_proto_] holds a special meaning with respect to an objects prototype chain so we can’t use it as the name of a key.
{color:#191918;}
bc. {color:#191918;}let base = {proto:1,b:2};
for (prop in obj) console.log(prop)
// bpre

Map

Map is a new data structure introduced in ES6 which lets you map keys to values without the drawbacks of using Objects.

Creating, getting and setting

We create a map using the
bc. {color:#191918;}new keyword, like so

{color:#191918;}
bc. {color:#191918;}let map = new Map();pre

We can then add entries by using the
bc. {color:#191918;}set method, like so:

{color:#191918;}
bc. {color:#191918;}let map = new Map();
map.set("A",1);
map.set("B",2);
map.set("C",3);pre

The set method is also chainable, like so:

{color:#191918;}
bc. {color:#191918;}let map = new Map()
    .set("A",1)
    .set("B",2)
    .set("C",3);pre

Or we could initialise the
bc. {color:#191918;}Map with a an array of key-value pairs, like so:

{color:#191918;}
bc. {color:#191918;}let map = new Map([
    [ "A", 1 ],
    [ "B", 2 ],
    [ "C", 3 ]
]);pre

We can extract a value by using the
bc. {color:#191918;}get method:

{color:#191918;}
bc. {color:#191918;}map.get("A");
// 1pre

We can check to see if a key is present using the
bc. {color:#191918;}has method:

{color:#191918;}
bc. {color:#191918;}map.has("A");
// truepre

We can delete entries using the
bc. {color:#191918;}delete method:

{color:#191918;}
bc. {color:#191918;}map.delete("A");
// truepre

We can check for the size (number of entries) using the
bc. {color:#191918;}size property:

{color:#191918;}
bc. {color:#191918;}map.size
// 2pre

We can empty an entire
bc. {color:#191918;}Map by using the
bc. {color:#191918;}clear method:

{color:#191918;}
bc. {color:#191918;}map.clear()
map.size
// 0pre

Looping over a Map

We use the
bc. {color:#191918;}for-of looping operator to loop over entries in a Map.

There are a couple of different method we can employ, we’ll go over each one using the below map as the example:

{color:#191918;}
bc. {color:#191918;}let map = new Map([
    [ "APPLE", 1 ],
    [ "ORANGE", 2 ],
    [ "MANGO", 3 ]
]);pre
Using keys()

The
bc. {color:#191918;}keys method returns the keys in the map as an array which we can loop over using
bc. {color:#191918;}for-of like so:

{color:#191918;}
bc. {color:#191918;}for (let key of map.keys()) {
    console.log(key);
}
// APPLE
// ORANGE
// MANGOpre
Using values()

The
bc. {color:#191918;}values method returns the values in the map as an array which we can loop over using
bc. {color:#191918;}for-of like so:

{color:#191918;}
bc. {color:#191918;}for (let value of map.values()) {
    console.log(value);
}
// 1:
// 2
// 3pre
Using entries()

The
bc. {color:#191918;}entries method returns the [key,value] pairs in the map as an array which we can loop over using
bc. {color:#191918;}for-of like so:

{color:#191918;}
bc. {color:#191918;}for (let entry of map.entries()) {
    console.log(entry[0], entry[1]);
}
// "APPLE" 1
// "ORANGE" 2
// "MANGO" 3pre

Using destructuring we can access the keys and values directly, like so:

{color:#191918;}
bc. {color:#191918;}for (let [key, value] of map.entries()) {
    console.log(key, value);
}
// "APPLE" 1
// "ORANGE" 2
// "MANGO" 3pre

Looping over key-value pairs via
bc. {color:#191918;}entries is so common that this is the default for a Map.

Therefore we don’t even need to call
bc. {color:#191918;}entries() on a map instance, like so:

{color:#191918;}
bc. {color:#191918;}for (let [key, value] of map) {
    console.log(key, value);
}
// "APPLE" 1
// "ORANGE" 2
// "MANGO" 3pre

{background:none;}

A distinction between Object and Map is that Maps record the order in which elements are inserted. It then replays that order when looping over keys, values or entries.

Set

Sets are a bit like maps but they only store keys not key-value pairs.

They are common in other programming languages but are a new addition to JavaScript in ES6.

Creating, getting and setting

We create a Set using the
bc. {color:#191918;}new keyword, like so

{color:#191918;}
bc. {color:#191918;}let set = new Set();pre

We can then add entries by using the
bc. {color:#191918;}add method, like so:

{color:#191918;}
bc. {color:#191918;}let set = new Set();
set.add('APPLE');
set.add('ORANGE');
set.add('MANGO');pre

The
bc. {color:#191918;}add method is chainable, like so:

{color:#191918;}
bc. {color:#191918;}let set = new Set()
    .add('APPLE')
    .add('ORANGE')
    .add('MANGO');pre

Or we can initialise the Set with an array, like so:

{color:#191918;}
bc. {color:#191918;}let set = new Set(['APPLE', 'ORANGE', 'MANGO']);pre

We can check to see if a value is in a set like so:

{color:#191918;}
bc. {color:#191918;}set.has('APPLE')
// truepre

We can delete a value from the set:

{color:#191918;}
bc. {color:#191918;}set.delete('APPLE')pre

We can count the number of entries in the set like so:

{color:#191918;}
bc. {color:#191918;}set.size
// 2pre

We can empty the entire set with the
bc. {color:#191918;}clear method:

{color:#191918;}
bc. {color:#191918;}set.clear();
set.size
// 0pre

Sets can only store unique values, so adding a value a second time has no effect:

{color:#191918;}
bc. {color:#191918;}let set = new Set();
set.add('Moo');
set.size
// 1
set.add('Moo');
set.size
// 1pre

Looping over a Set

We can use the
bc. {color:#191918;}for-of loop to loop over items in our set, like so:

{color:#191918;}
bc. {color:#191918;}let set = new Set(['APPLE', 'ORANGE', 'MANGO']);
for (let entry of set) {
    console.log(entry);
}
// APPLE
// ORANGE
// MANGOpre

{background:none;}

Similar to Maps, Sets also record the order in which elements are inserted, it then replays that order when looping.

Summary

Map and Set are great additions to JavaScript in ES6.

We no longer have to deal with Map and Sets poor cousin the Object and it’s many drawbacks.

Listing

http://plnkr.co/edit/IXnaorsOWB1XuaePtyf4?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}'use strict';

// Map
let map = new Map();
map.set(“A”, 1);
map.set(“B”, 2);
map.set(“C”, 3);

let map2 = new Map() .set(“A”, 1) .set(“B”, 2) .set(“C”, 3);

let map3 = new Map([ [“A”, 1], [“B”, 2], [“C”, 3]
]);

for (let [key, value] of map) { console.log(key, value);
}

console.log(map.get(“A”));
console.log(map.has(“A”));
console.log(map.size);

map.delete(“A”);
console.log(map.size);

map.clear();
console.log(map.size);

// Set
let set = new Set();
set.add(‘APPLE’);
set.add(‘ORANGE’);
set.add(‘MANGO’);

let set2 = new Set() .add(‘APPLE’) .add(‘ORANGE’) .add(‘MANGO’);

let set3 = new Set([‘APPLE’, ‘ORANGE’, ‘MANGO’]);

console.log(set.has(‘APPLE’));

set.delete(‘APPLE’);

console.log(set.size);

set.clear();
console.log(set.size);

let set4 = new Set();
set3.add(‘Moo’);
console.log(set3.size);
// 1
set4.add(‘Moo’);
console.log(set4.size);
// 1

for (let entry of set2) { console.log(entry);
}pre

PROMISES

When you execute a task synchronously, you wait for it to finish before moving on to the next line of code.

When you execute a task asynchronously, the program moves to the next line of code before the task finishes.

Think of synchronous programming like waiting in line and asynchronous programming like taking a ticket. When you take a ticket you can go do other things and then be notified when ready.

Callbacks

One way to program asynchronously is to use callbacks. We pass to an asynchronous function a function which it will call when the task is completed.

{color:#191918;}
bc. {color:#191918;}function doAsyncTask(cb) {
  setTimeout(() => {
    console.log("Async Task Calling Callback");
    cb();
  }, 1000);
}

doAsyncTask(() => console.log(“Callback Called”));pre

The
bc. {color:#191918;}doAsyncTask function when called kicks of an asynchronous task and returns immediately.

To get notified when the async task completes we pass to
bc. {color:#191918;}doAsyncTask a function which it will call when the task completes.

It’s called a callback function,
bc. {color:#191918;}cb for short, because it calls-you-back.

Promise API

In ES6 we have an alternative mechanism built into the language called a promise.

A promise is a placeholder for a future value.

It serves the same function as callbacks but has a nicer syntax and makes it easier to handle errors.

Creating a Promise

We create an instance of a promise by calling
bc. {color:#191918;}new on the
bc. {color:#191918;}Promise class, like so:

{color:#191918;}
bc. {color:#191918;}var promise = new Promise((resolve, reject) => {
});pre

We pass to Promise an inner function that takes two arguments
bc. {color:#191918;}(resolve, reject).

Since we are defining the function we can call these arguments whatever we want but the convention is to call them
bc. {color:#191918;}resolve and
bc. {color:#191918;}reject.

{color:#191918;}resolve and
bc. {color:#191918;}reject are in fact functions themselves.

Inside this inner function we perform our asynchronous processing and then when we are ready we call
bc. {color:#191918;}resolve(), like so:

{color:#191918;}
bc. {color:#191918;}var promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log("Async Work Complete");
    resolve();
  }, 1000);
});pre

We usually return this promise from a function, like so:

{color:#191918;}
bc. {color:#191918;}function doAsyncTask() {
  var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("Async Work Complete");
      resolve();
    }, 1000);
  });
  return promise;
}pre

If there was an error in the async task then we call the
bc. {color:#191918;}reject() function like so:

{color:#191918;}
bc. {color:#191918;}function doAsyncTask() {
  var promise = new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log("Async Work Complete");
      if (error) {
        reject();
      } else {
        resolve();
      }
    }, 1000);
  });
  return promise;
}pre

Promise Notifications

We can get notified when a promise
bc. {color:#191918;}resolves by attaching a success handler to its
bc. {color:#191918;}then function, like so:

{color:#191918;}
bc. {color:#191918;}doAsyncTask().then(() => console.log("Task Complete!"));pre
{color:#191918;}then can take two arguments, the second argument is a [_error_] handler that gets called if the promise is
bc. {color:#191918;}rejected, like so:
{color:#191918;}
bc. {color:#191918;}doAsyncTask().then(
  () => console.log("Task Complete!"),
  () => console.log("Task Errored!"),
);pre

Any values we pass to the
bc. {color:#191918;}resolve and
bc. {color:#191918;}reject functions are passed along to the error and success handlers, like so:

{color:#191918;}
bc. {color:#191918;}let error = true;
function doAsyncTask() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (error) {
        reject('error'); // pass values
      } else {
        resolve('done'); // pass values
      }
    }, 1000);
  });
}

doAsyncTask().then( (val) => console.log(val), (err) => console.error(err)
);pre

Immediate Resolution or Rejection

We can create an immediately resolved Promise by using the
bc. {color:#191918;}Promise.resolve() method, like so:

{color:#191918;}
bc. {color:#191918;}let promise = Promise.resolve('done');pre

And an immediately rejected Promise by using the
bc. {color:#191918;}Promise.reject() method, like so:

{color:#191918;}
bc. {color:#191918;}let promise = Promise.reject('fail');pre

One of the nice things about Promises is that if we add a
bc. {color:#191918;}then handler after the promise resolves or rejects the handler still gets called.

{color:#191918;}
bc. {color:#191918;}let promise = Promise.resolve('done');
promise.then((val) => console.log(val)); // 'done'pre

In the above example, even though the Promise has resolved before we added the success handler, the promise framework still calls the success handler.

Chaining

We can also connect a series of
bc. {color:#191918;}then handlers together in a chain, like so:

{color:#191918;}
bc. {color:#191918;}Promise.resolve("done")
  .then(
    (val) => {
      console.log(val);
      return 'done2';
    },
    (err) => console.error(err)
  )
  .then(
    (val) => console.log(val),
    (err) => console.error(err)
  );
// 'done'
// 'done2'pre

Promises pass an error along the chain till it finds an error handler. So we don’t need to define an error handler for each
bc. {color:#191918;}then function, we can just add one at the end like so:

{color:#191918;}
bc. {color:#191918;}Promise.reject('fail')
  .then((val) => console.log(val))
  .then(
    (val) => console.log(val),
    (err) => console.error(err)
  );pre

If we throw an exception from our promise function or one of the success handlers, the promise gets rejected and the error handler is called, like so:

{color:#191918;}
bc. {color:#191918;}Promise.resolve('done')
  .then((val) => {
    throw new Error("fail")
  })
  .then(
    (val) => console.log(val),
    (err) => console.error(err)
  );
// [Error: fail]pre

Catch

The
bc. {color:#191918;}catch function works exactly the same way as the
bc. {color:#191918;}then error handler, it’s just clearer and more explicitly describes our intent to handle errors.

{color:#191918;}
bc. {color:#191918;}Promise.resolve('done')
  .then((val) => {throw new Error("fail")})
  .then((val) => console.log(val))
  .catch((err) => console.error(err));pre

Summary

Promises are a far cleaner solution to writing asynchronous code than callbacks.

The resulting code that’s created is easier to read and is often written the order the application will execute.

So it can be easier to trace through code in your head.

With the
bc. {color:#191918;}catch handler it also gives us a single place where we can handle errors.

Listing

http://plnkr.co/edit/OMGgN6qpED6wTEEP2XYN?p=preview

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}'use strict';

// Via callbacks
/* function doAsyncTask(cb) { setTimeout(() => { console.log(“Async Task Calling Callback”); cb(); }, 1000); }

doAsyncTask(() => console.log(“Callback Called”)); */

// Via Promise
let error = false;
function doAsyncTask() { return new Promise((resolve, reject) => { setTimeout(() => { if (error) { reject(‘error’); } else { resolve(‘done’); } }, 1000); });
}

doAsyncTask().then( (val) => console.log(val), (err) => console.error(err)
);

// Immediately Resolved Promise
let promise = Promise.resolve(‘done’);
promise.then((val) => console.log(val)); // ‘done’

// Handling Errors
Promise.resolve(‘done’) .then((val) => {throw new Error(“fail”)}) .then((val) => console.log(val)) .catch((err) => console.error(err));pre

CLASS & INTERFACE

How do we write object orientated code in ES6?

Object Orientation in JavaScript

JavaScript has a prototype-based, object-oriented programming model. It creates objects using other objects as blueprints and to implement inheritance it manipulates what’s called a prototype chain.

We normally call the way object orientation is implemented in C++ or Java as the Classical OO Pattern and the way it’s implemented in JavaScript as the Prototype Pattern.

Although the prototype pattern is a valid way to implement object orientation it can be confusing for newer javascript developers or developers used to the classical pattern.

So in ES6 we have an alternative syntax, one that closer matches the classical object orientated pattern as is seen in other languages.

{background:none;}

Under the hood the new syntax still uses the prototype pattern with constructor functions and the prototype-chain. However, it provides a more common and convenient syntax with less boilerplate code.

{background:none;}

TypeScript supports the ES6
bc. {color:#191918;}class syntax but also adds some other feature like access modifiers and interfaces, so in this lecture we’ll be writing TypeScript rather than pure ES6.

Class

A
bc. {color:#191918;}class is a blueprint for creating objects with specific functions and properties already attached to it, lets go through a simple example line by line:

{color:#191918;}
bc. {color:#191918;}class Person { [_{color:#468C54;}①_]
    firstName = ""; [_{color:#468C54;}②_]
    lastName = "";
    constructor(firstName, lastName) { [_{color:#468C54;}③_]
        this.firstName = firstName;
        this.lastName = lastName;
    }
name() { return `${this.firstName} ${this.lastName}`; } whoAreYou() { return `Hi i’m ${this.name()}`; } }pre

{color:#191918;}

  1. {color:#191918;} We define a class using then
    bc. {color:#191918;}class keyword.
  1. {color:#191918;} We describe the properties we want on our class instance.
  1. {color:#191918;} Each class has a special
    bc. {color:#191918;}constructor function, this is called when we create an instance of a class with
    bc. {color:#191918;}new
  1. {color:#191918;} We describe the functions, also known as methods, that we want on our class instance.
  1. {color:#191918;}
    bc. {color:#191918;}this in a method points to the class instance, the object that is created using this class.

Class Instance

A class is a blueprint for creating an object, we call that created object an instance of a class, or a class instance or just instance for short.

We instantiate a class by using the
bc. {color:#191918;}new keyword and when that happens javascript calls the
bc. {color:#191918;}constructor function. We can pass to the constructer arguments which it uses to initialise properties or call other function, like so:

{color:#191918;}
bc. {color:#191918;}let asim = new Person("Asim","Hussain");pre

The above creates an instance of the Person class called asim.

The asim instance has the same properties and functions that are described on the Person class:

{color:#191918;}
bc. {color:#191918;}let asim = new Person("Asim","Hussain");
asim.whoAreYou()
// "Hi i'm Asim Hussain"pre

Inheritance

A class can inherit from another class. We can create a class blue-print that extends an existing class blue-print by adding other methods or properties.

We do this by using the
bc. {color:#191918;}extends keyword, like so:

{color:#191918;}
bc. {color:#191918;}class Student extends Person { [_{color:#468C54;}①_]
    course; [_{color:#468C54;}②_]
constructor(firstName, lastName, course) { super(firstName, lastName); this.course = course; } whoAreYou() { return `${super.whoAreYou()} and i’m studying ${this.course}`; } }pre

{color:#191918;}

  1. {color:#191918;} We use the
    bc. {color:#191918;}extends keyword to signal that this class inherits all the properties and methods from the parent Person class.
  1. {color:#191918;} We can describe additional properties.
  1. {color:#191918;} We use the
    bc. {color:#191918;}super function to call the constructor of the parent class
  1. {color:#191918;} We can override member functions of the parent class with our own versions.
  1. {color:#191918;} In member functions
    bc. {color:#191918;}super refers to the
    bc. {color:#191918;}parent instance.

We can then instantiate this derived class like so:

{color:#191918;}
bc. {color:#191918;}let asim = new Student("Asim", "Hussain", "Angular 2");
console.log(asim.whoAreYou());
// Hi i'm Asim Hussain and i'm studying Angular 2pre

Access Modifiers

Everything we have learned so far about classes is pure ES6 JavaScript.

However TypeScript adds some nice functionality on top of ES6 classes, namely function and property visibility via access modifiers.

For example we can define the properties of our Person class as
bc. {color:#191918;}private, like so:

{color:#191918;}
bc. {color:#191918;}class Person {
    private firstName = "";
    private lastName = "";
constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } }pre

And we create a function on our Student class called
bc. {color:#191918;}test() which tries to access one of these properties, like so:

{color:#191918;}
bc. {color:#191918;}class Student extends Person {
  .
  .
  .
  test() {
    console.log(this.firstName);
  }
}pre

And we tried to call this function from our
bc. {color:#191918;}Student instance, like so:

{color:#191918;}
bc. {color:#191918;}let asim = new Student("Asim", "Hussain", "Angular 2");
console.log(asim.test());pre

Compiling the above with typescript prints out this error:

{color:#191918;}
bc. {color:#191918;}error TS2341: Property 'firstName' is private and only accessible within class 'Person'.pre

By marking the
bc. {color:#191918;}firstName property as
bc. {color:#191918;}private it is now only visible from one of the methods on
bc. {color:#191918;}Person class.

We can also define class methods as
bc. {color:#191918;}private with the same effect. If we tried to call a
bc. {color:#191918;}private method from outside of a Person class, the typescript transpiler throws an error.

There are 3 access modifiers:

{color:#191918;}
{color:#191918;}
public

{color:#191918;} This is the default and means its visible everywhere.

{color:#191918;}
private

{color:#191918;} Only member functions of the class it’s declared in can see this.

{color:#191918;}
protected

{color:#191918;} Only the class it’s declared in and any class that inherits from that class can see this.

Constructor shortcut

A really common pattern in constructors is to use them to initialise properties via arguments you pass into the constructor, like in our example:

{color:#191918;}
bc. {color:#191918;}class Person {
    private firstName = "";
    private lastName = "";
constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } }pre

As long as you are using an access modifier TypeScript lets us shorten this to:

{color:#191918;}
bc. {color:#191918;}class Person {
    constructor(private firstName, private lastName) {
    }
}pre

Interfaces

TypeScript has another feature called an
bc. {color:#191918;}interface. An interface can be used in a number of scenarios but by far the most common is when used with classes.

When used with classes the syntax looks like this:

{color:#191918;}
bc. {color:#191918;}class Person implements Human {
}pre
{color:#191918;}Human in the example above is an [_interface_]. An interface lets you describe the [_minimum_] set of [*public*] facing properties or methods that a
bc. {color:#191918;}class has.

Another way interfaces are explained is that they describe a set of rules the class has to follow, a contract it has to adhere to.

So for us a
bc. {color:#191918;}Human interface might look like:

{color:#191918;}
bc. {color:#191918;}interface Human {
    firstName: string;
    lastName: string;
}pre

{background:none;}

Since interfaces are all about the public interface of a class they can’t have access modifiers, the properties above have to be public.

If the Person class then doesn’t implement at least a
bc. {color:#191918;}firstName and a
bc. {color:#191918;}lastName then typescript throws an error like so:

{color:#191918;}
bc. {color:#191918;}error TS2420: Class 'Person' incorrectly implements interface 'Human'. Property 'firstName' is missing in type 'Person'.pre

Sometimes however we might want an interface to describe an optional contract. We can append
bc. {color:#191918;}? to the name of the property or function to mark it as optional, like so:

{color:#191918;}
bc. {color:#191918;}interface Human {
    firstName: string;
    lastName: string;
                name?: Function;
                isLate?(time: Date): Function;
}pre

Summary

In ES6 we now have a new way of writing object oriented code with the
bc. {color:#191918;}class syntax.

We can inherit methods and properties of one class into another by using the
bc. {color:#191918;}extends keyword.

Under the hood we are still using prototype based inheritance but the syntax is easier to understand and more familiar for developers who are coming from other languages.

TypeScript adds some extra functionality on-top of ES6 classes such as access modifiers and interfaces

Listing

https://github.com/codecraftpro/angular2-sample-code/blob/master/2.es6-typescript/10.class-interface/script.ts

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}interface Human {
  firstName: string;
  lastName: string;
  name?: Function;
  isLate?(time: Date): Function;
}

class Person implements Human { constructor(public firstName, public lastName) { }

public name() { return `${this.firstName} ${this.lastName}`; } protected whoAreYou() { return `Hi i’m ${this.name()}`; } }

class Student extends Person { course;

constructor(firstName, lastName, course) { super(firstName, lastName); this.course = course; } whoAreYou() { return `${super.whoAreYou()} and i’m studying ${this.course}`; } }

let asim = new Student(“Asim”, “Hussain”, “typescript”);
console.log(asim.whoAreYou());pre

DECORATORS

We’ve seen in the quickstart that in Angular we can decorate a class with extra info using the
bc. {color:#191918;}@ syntax, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
        selector: "thingy",
        template: `foo`
})
class MyComponent {
}pre

This is a new feature that will probably make it into the ES7 version of JavaScript, it’s not available right now however even in the ES6 version.

However the functionality is available in TypeScript, so we can already make use it.

It allows us to decorate classes and functions, similar to annotations in java and decorators in python.

Specific Angular implementations might be more complex and harder to read and understand but the concept is actually quite simple.

Simple no-argument decorator

I’m going to explain by creating a decorator called
bc. {color:#191918;}@course for our Person class

{color:#191918;}
bc. {color:#191918;}@course
class Person {
    firstName;
    lastName;
constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; } }pre
{color:#191918;}@course is just a [_function_], like so:
{color:#191918;}
bc. {color:#191918;}function course(target) {
    Object.defineProperty(target.prototype, 'course', {value: () => "Angular 2"})
}pre

The first argument to the
bc. {color:#191918;}course function is the
bc. {color:#191918;}target.

This is the thing the decorator is attached to, so for a class it’s going to be the function constructor for that class, the under-the-hood implementation of a class.

Knowing this we can actually dynamically add a function to our Person class by using the
bc. {color:#191918;}Object.defineProperty function,

The details of the
bc. {color:#191918;}Object.defineProperty function are beyond the scope of this chapter. We use it to add a function called
bc. {color:#191918;}course onto the class it decorates and for now this function just returns the string “Angular 2”.

We can now call
bc. {color:#191918;}asim.course() and this prints out
bc. {color:#191918;}“Angular 2“:

{color:#191918;}
bc. {color:#191918;}let asim = new Person("Asim", "Hussain");
console.log(asim.course()); // Angular 2pre

Decorators with arguments

But how do we pass arguments to our decorator, like the way the
bc. {color:#191918;}@Component decorator works?

We create a function that returns a decorator, like so:

{color:#191918;}
bc. {color:#191918;}function Course(config) { // 1
  return function (target) {
    Object.defineProperty(
        target.prototype,
        'course',
        {value: () => config.course} // 2
    )
  }
}pre

{color:#191918;}

  1. {color:#191918;}
    We pass a
    bc. {color:#191918;}config object to the outer
    bc. {color:#191918;}Course function.
  1. {color:#191918;}
    Then use that
    bc. {color:#191918;}config in the returned inner decorator function.

Now we can use this decorator like so:

{color:#191918;}
bc. {color:#191918;}@Student({
    course: "Angular 2"
})
class Person {
}pre

Summary

Decorators are a new feature of TypeScript and used throughout the Angular 2 code, but they are nothing to be scared of.

With decorators we can configure and customise our classes at design time.

They are just functions that can be used to add meta-data, properties or functions to the thing they are attached to.

A collection of useful decorators, for use in your projects or just to read and learn, can be found here: https://github.com/jayphelps/core-decorators.js

Listing

https://github.com/codecraftpro/angular2-sample-code/blob/master/2.es6-typescript/11.decorators/script.ts

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}function Student(config) {
    return function (target) {
        Object.defineProperty(target.prototype, 'course', {value: () => config.course})
    }
}

@Student({ course: “angular3”
})
class Person { constructor(private firstName, private lastName) { }

public name() { return `${this.firstName} ${this.lastName}`; } protected whoAreYou() { return `Hi i’m ${this.name()}`; } }

let asim = new Person(“Asim”, “Hussain”);
//noinspection TypeScriptUnresolvedFunction
console.log(asim.course());pre

MODULES

Module Loading

By default javascript doesn’t have a module system like other languages, e.g. Java or Python.

This means that if you wanted to call a function in some other file, you have to remember to explicitly load that file via script tags before you call the function.

If you tried to use code that you forgot to add via a script tag, then javascript would complain.

Other languages have a module loading system e.g. in python if you wanted to use some code from another file you would type something like

{color:#191918;}
bc. {color:#191918;}import foo from bar;
foo();pre

The language itself figured out where
bc. {color:#191918;}bar was, loaded it up from the filesystem, extracted the function
bc. {color:#191918;}foo and made it available to you in your file to use.

This feature was missing in JavaScript so the community developed their own solutions, such as CommonJS which is used in node.

ES6 Modules

ES6 took the best of the existing module systems and introduced this concept on a language level.

Although it’s made it into the ES6 standard it’s up to the javascript engine makers to actually implement it natively and they haven’t… yet.

So until that happens we code using the ES6 module syntax in TypeScript. When typescript transpiles the code to ES5 it uses the CommonJS module loading system which we touched on above.

{background:none;}

We can configure TypeScript to use other module loaders, but the default is CommonJS.

Exporting

{color:#191918;}
bc. {color:#191918;}// utils.ts
function square(x) {
    return Math.pow(x,2)
}

function cow() { console.log(“Mooooo!!!”)
}

export {square, cow};pre

We declare some functions in a file.

By using the
bc. {color:#191918;}export keyword we say which of those functions can be exported, and therefore imported and used in other modules.

{background:none;}

{color:#191918;}{square, cow} is just destructuring syntax and is short for
bc. {color:#191918;}{square: square, cow: cow}.

Importing

{color:#191918;}
bc. {color:#191918;}// script.ts
import {square, cow} from './utils';

console.log(square(2));
cow();pre

{background:none;}

To compile with typescript we need to provide both files on the command line
bc. {color:#191918;}tsc -t ES5 -w utils.ts script.ts

We again use that destructuring syntax to import the functions we want from the utils module, we provide a path relative to this module.

Aliases

We may want to import a function with one name but then use it via another name. Perhaps to avoid name collisions or just to have a more convenient naming, like so:

{color:#191918;}
bc. {color:#191918;}import {square as sqr} from './utils';
sqr(2);pre

Or we can import everything in a file like so:

{color:#191918;}
bc. {color:#191918;}import * as utils from './utils';
console.log(utils.square(2));
utils.cow();pre

Alternative export syntax

As well as describing the exports by using the export keyword, like so:

{color:#191918;}
bc. {color:#191918;}export {square, cow};pre

We can also export functions or variables as they are defined by prepended the word
bc. {color:#191918;}export to the front of their declarations:

{color:#191918;}
bc. {color:#191918;}export function square(x) {
    return Math.pow(x,2)
}pre

Default exports

If a module defines one export which is the most common, we can take advantage of the default export syntax, like so:

{color:#191918;}
bc. {color:#191918;}export default function square(x) {
    return Math.pow(x,2)
}pre

And then when we import it we don’t need to use
bc. {color:#191918;}{
bc. {color:#191918;}}, like so:

{color:#191918;}
bc. {color:#191918;}import square from './utils';pre

Or, if we want to import the default export as well as some other exports, we can use:

{color:#191918;}
bc. {color:#191918;}import square, { cow } from './utils';pre

Summary

With ES6 modules we finally have a mechanism for letting the language deal with loading of dependant files for us.

This isn’t baked into javascript engines yet. So to solve this problem in Angular 2 we still use the ES6 module loading syntax but leave it to TypeScript to transpile to CommonJS.

Listing

https://github.com/codecraftpro/angular2-sample-code/tree/master/2.es6-typescript/12.modules

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}import square, {cow} from './utils';
console.log(square(4));
cow();pre

Listing 2. utils.js

{color:#191918;}
bc. {color:#191918;}export default function square(x) {
  return Math.pow(x, 2)
}

export function cow() { console.log(“Mooooo!!!”)
}pre

TYPES

Transpile-time type checking

Some of the most common mistakes we make while writing JavaScript code is to misspell a property or a method name.

We only find out about the mistake when we get a runtime error, that is to say when we are running our application.

{background:none;}

This is why testing is so important for javascript applications, only running them can surface errors.

Other languages like C++ or Java have something called type checking, during a compilation phase it first checks for some simple mistakes in the code and raises an error if it finds any.

TypeScripts transpilation mechanism also performs type checking, however it only works when we tell TypeScript the type of things.

e.g. in javascript we might write:

{color:#191918;}
bc. {color:#191918;}let a;
a = 1;
a = '2';pre

We expected the type of the
bc. {color:#191918;}a variable to remain a number over its life. But by mistake we assigned a string
bc. {color:#191918;}‘2‘ to
bc. {color:#191918;}a, this doesn’t cause an error in JavaScript.

Only if one of the functions which depends on
bc. {color:#191918;}a starts misbehaving do we even get a clue that something might be wrong.

However with typescript we can clearly state that we want the
bc. {color:#191918;}a variable to always hold a number, like so:

{color:#191918;}
bc. {color:#191918;}let a: number = 1;pre

Then if somewhere else in our code we wrote:

{color:#191918;}
bc. {color:#191918;}a = "1";pre

We get this error:

{color:#191918;}
bc. {color:#191918;}error TS2322: Type 'string' is not assignable to type 'number'.pre

If we take advantage of types in typescript the transpiler will warn us with a transpile-time errors.

Supported Types

Basic Types

We can support boolean, number and string.

{color:#191918;}
bc. {color:#191918;}let decimal: number = 6;
let done: boolean = false;
let color: string = "blue";pre

Arrays

We have two ways of describing the types of arrays.

The first is to use the brackets notation
bc. {color:#191918;}[], like so:

{color:#191918;}
bc. {color:#191918;}let list: number[] = [1, 2, 3];pre

The above indicates to TypeScript that this array should only hold numbers.

The second way uses a generic type specifically
bc. {color:#191918;}Array, like so:

{color:#191918;}
bc. {color:#191918;}let list: Array<number> = [1, 2, 3];pre

{background:none;}

We cover generics in more detail later on in this lecture.

Functions

We can describe a variable as one that will only point to a function, like so:

{color:#191918;}
bc. {color:#191918;}let fun: Function = () => console.log("Hello");pre

With TypeScript we can also define the expected return type of a function, like so:

{color:#191918;}
bc. {color:#191918;}function returnNumber(): number {
  return 1;
}pre

The above lets TypeScript know that the function should only return a number.

Enum

An Enum is a datatype consisting of a set of named values. The names are usually identifiers that behave as constants. Enums were introduced in ES6.

{color:#191918;}
bc. {color:#191918;}enum Direction {
    Up,
    Down,
    Left,
    Right
}

let go: Direction;
go = Direction.Up;pre

Class & Interface

Classes and Interfaces, whether created by you or others, are also types of things. So we can use them where we would use any of the built-in types:

{color:#191918;}
bc. {color:#191918;}class Person {};
let person: Person;
let people: Person[];pre

Any

If we don’t know the type of something we can fall back to using
bc. {color:#191918;}any.

If used it doesn’t provide any type checking but does make it clear that we intentionally don’t know the type, rather than we forgot to add the type.

{color:#191918;}
bc. {color:#191918;}let notsure: any = 1;
notsure = "hello"; // This is fine since we don't do type checking with anypre

Void

{color:#191918;}void means no type, it’s typically used to indicate that a function will not return anything at all, like so:
{color:#191918;}
bc. {color:#191918;}function returnNothing(): void {
  console.log("Moo");
}pre

Type Assertion

Sometimes we end up in a situation where we know more than TypeScript about the type of something. In those situations we can use type assertions as a hint to the transpiler about the type of something, like so:

{color:#191918;}
bc. {color:#191918;}let value: any = "Asim Hussain";
let length: number = (<string>value).length;pre
{color:#191918;}(<string>value) lets TypeScript know that we believe the type of value to be string.

Generics

How can we create re-usable bits of code which can still take advantage of typescripts transpile-time type checking?

Take for instance this example:

{color:#191918;}
bc. {color:#191918;}class Audio {}
class Video {}
class Link {}
class Text {}

class Post { content: any;
}pre

We have a class called Post which has a
bc. {color:#191918;}content property. The content might be an instance of Audio, Video, Link or Text classes.

We could ignore the type of content and just use
bc. {color:#191918;}any like the example above but this doesn’t give us the benefit of type checking.

We can create seperate
bc. {color:#191918;}AudioPost,
bc. {color:#191918;}VideoPost,
bc. {color:#191918;}LinkPost and
bc. {color:#191918;}TextPost types, like so:

{color:#191918;}
bc. {color:#191918;}class AudioPost {
    content: Audio;
}

class VideoPost { content: Video;
}

class LinkPost { content: Link;
}

class TextPost { content: Text;
}pre

But apart from being verbose and time-consuming it assumes we know all the content types upfront. Maybe a consumer later on would like to create a
bc. {color:#191918;}VRPost type.

With generics we can dynamically generate a new type by passing into the Post type a type variable, like so:

{color:#191918;}
bc. {color:#191918;}class Audio {}
class Video {}
class Link {}
class Text {}

class Post { content: any;
}pre

{color:#191918;}<T> above is the [_generic_] syntax and
bc. {color:#191918;}T is the [_type variable_]. We could name it anything but the convention if there is only one is to call it just
bc. {color:#191918;}T.

Then we can use
bc. {color:#191918;}T wherever we would use a type, like so:

{color:#191918;}
bc. {color:#191918;}class Post<T> {
    content: T;
}pre

Finally when we want to create a specific type of Post we can declare it like so:

{color:#191918;}
bc. {color:#191918;}let videoPost: Post<Video>;pre

Optional Types

By default we don’t have to add types when using TypeScript, we could just leave them out.

{color:#191918;}
bc. {color:#191918;}let answer;
answer = 42;pre

TypeScript won’t perform any type checking for the above and assumes a type of
bc. {color:#191918;}any.

{background:none;}

This behaviour is controlled by the
bc. {color:#191918;}noImplicitAny flag in
bc. {color:#191918;}tsconfig.json. If set to
bc. {color:#191918;}false then TypeScript assumes
bc. {color:#191918;}any for missing types, of set to
bc. {color:#191918;}true then TypeScript throws an error if no type is present.

Opinion is split as to whether to keep this to
bc. {color:#191918;}true or
bc. {color:#191918;}false, by default it’s set to
bc. {color:#191918;}false which is more forgiving but then doesn’t force developers to use types which is the point of TypeScript.

Type Inference.

If a variable is declared and initialised on one line TypeScript will try to infer, guess, the type of a variable by how it’s declared, for example:

{color:#191918;}
bc. {color:#191918;}let answer = 42;
answer = "42";pre

TypeScript inferred that the type of answer was number by the fact we initialised it with a number. When we later on try to assign a string to
bc. {color:#191918;}answer it throws an error.

{color:#191918;}
bc. {color:#191918;}error TS2322: Type 'string' is not assignable to type 'number'.pre

Types for external libraries

This is all fine for code that’s written in TypeScript and has types.

What if you wanted to use code that wasn’t written in TypeScript or which you are not going to include as TypeScript and compile yourself.

We can use something called an ambient type definition.

This is a file that contains meta-data about the types in another library, a meta-type file.

This repository (https://github.com/DefinitelyTyped/DefinitelyTyped) contains type definitions for some of the most popular 3rd party javascript libraries.

To use them in a file we simply:-

{color:#191918;}

  1. {color:#191918;}
    Download the associated type file, for example
    bc. {color:#191918;}jquery.d.ts.
  1. {color:#191918;}
    In the typescript file where we want to use the 3rd party library, add this to the top of the file:
{color:#191918;}
bc. {color:#191918;}/// <reference path="jquery.d.ts" />pre

typings

Thats a bit cumbersome so there is also a command line tool you can use called
bc. {color:#191918;}typings which handles the leg-work for you.

We install it via
bc. {color:#191918;}npm, like so:

{color:#191918;}
bc. {color:#191918;}npm install -g typingspre

In our project folder we then initialise a config file by typing
bc. {color:#191918;}typings init this creates a
bc. {color:#191918;}typings.json file.

Then we can install type definition files like so:

{color:#191918;}
bc. {color:#191918;}typings install jquery --save --source dt --globalpre

This downloads and installs the type definition files to the
bc. {color:#191918;}./typings folder and conveniently bundles all of the downloaded files into a single file called
bc. {color:#191918;}index.d.ts.

So then to use jQuery with typescript type support we just need to add a reference to
bc. {color:#191918;}index.d.ts to the top the file where we use jQuery.

{color:#191918;}
bc. {color:#191918;}/// <reference path="./typings/index.d.ts"/>pre

Summary

With transpile-time type checking TypeScript can help uncover bugs much earlier and faster than if they were to manifest at run-time.

Using types is optional but highly recommended by the Angular team.

If using 3rd party libraries that have already been transpiled into javascript, typescript can still perform transpile-time type checking if we include the type definition file for the library.

Listing

https://github.com/codecraftpro/angular2-sample-code/blob/master/2.es6-typescript/13.types/script.ts

Listing 1. script.js

{color:#191918;}
bc. {color:#191918;}"use strict";

// Core
let decimal: number = 6;
let done: boolean = false;
let color: string = “blue”;
let list: number[] = [1, 2, 3];
let list2: Array = [1, 2, 3];

// Function
let fun: Function = () => console.log(“Hello”);
function returnNumber(): number { return 1;
}

// Void
function returnNothing(): void { console.log(“Moo”);
}

// Enum
enum Direction { Up, Down, Left, Right
}
let go: Direction;
go = Direction.Up;

// Class
class Person {
}
let person: Person;
let people: Person[];

// Any
let notsure: any = 1;
notsure = “hello”; // This is fine since we don’t do type checking with any

// Type Assertion
let value: any = “Asim Hussain”;
let length: number = (value).length;

// Generics
class Audio {
}
class Video {
}

class Post { content: T;
}

let audioPost: Post

WRAPPING UP

In this section we covered the basics of ES6 JavaScript and TypeScript.

We discussed how TypeScript is a super-set of ES6 JavaScript.

We explained how to install the command line tools so you can transpile TypeScript locally on your computer.

We covered the core features of ES6 such as
bc. {color:#191918;}let,
bc. {color:#191918;}const, template strings, fat arrow functions;
bc. {color:#191918;}for-of loops, Map and Set; as well as how to deal with asynchronous programming by using Promises.

With TypeScript we covered classes, class access modifiers, interfaces; decorators, modules and types including generic types.

We’ve covered a lot of topics but still this is just the essentials required to build Angular 2 applications, there is more to learn in each of these areas.

Further Reading

If you would like to learn more about ES6 I recommend reading this book (it’s free): https://github.com/getify/You-Dont-Know-JS/tree/master/es6%20%26%20beyond

If you would like to learn more about TypeScript the official documentation is a good place to start: https://www.typescriptlang.org/docs/tutorial.html

ANGULAR CLI

Angular now comes with a command line interface (CLI) to make it easier and faster to build Angular applications.

{background:none;}

The Angular CLI at the time of writing (09/2016) is still in a prototype stage and has a number of issues that still need to be addressed. The biggest is that it doesn’t currently work with the Angular router.

Even without support for the router however the CLI is a useful if not essential tool.

Features

The Angular CLI helps with:

{color:#191918;}
{color:#191918;}
Bootstrapping a project

{color:#191918;} It creates the initial project structure with a root bc. {color:#191918;}NgModule and a root component and bootstraps it using the bc. {color:#191918;}platformBootstrapDynamic method.

The project is also configured to use the webpack loader which handles things like module loading, bundling and minification of dependant code.

{background:none;}

In the course we’ve used SystemJS for this since webpack doesn’t work with Plunker yet. We’ll continue to use SystemJS for the code samples in Plunker and WebPack for any applications created with the Angular CLI.

{color:#191918;}
Serving and live reloading

{color:#191918;} The CLI starts a local web-server so we can view our application in the browser via localhost:4000.

The CLI also watches for any changes to our files and automatically reloads the webpage if there are any.

{color:#191918;}
Code generation

{color:#191918;} Using the CLI we can create components directives, services, pipes etc…​ all from the command line with all the necessary files, folders and boilerplate code included.

All the generated code adheres to the official Angular style guide.

{background:none;}

In Angular 1 the Angular team never supported an official style guide. This meant that most projects ended up looked pretty different to each other. A developer moving teams would have to figure out from scratch how this team likes to write Angular 1 code.

{color:#191918;}
Testing

{color:#191918;} The generated code also comes with bootstrapped jasmine test spec files, we can use the CLI to compile and run all the tests with a single command.

Whenever the CLI detects changes to any file it re-runs all the tests automatically in the background.

{color:#191918;}
Packaging and releasing

{color:#191918;} The CLI doesn’t just stop with development, using it we can also package our application ready for release to a server.

Installing the Angular CLI

To install the CLI we use Node and npm.

{color:#191918;}
bc. {color:#191918;}npm install -g angular-clipre

If the above ran successfully it will have made available to you a new application called
bc. {color:#191918;}ng, to test this installed correctly run this command:

{color:#191918;}
bc. {color:#191918;}ng -vpre

It should output the version of the application that was installed, like so:

{color:#191918;}
bc. {color:#191918;}angular-cli: 1.0.0-beta.15
node: 6.4.0
os: darwin x64pre

Start an application with
bc. {color:#191918;}ng new

Lets create a new project called
bc. {color:#191918;}codecraft.

To bootstrap our new project with
bc. {color:#191918;}ng we run this command:

{color:#191918;}
bc. {color:#191918;}ng new codecraftpre

{background:none;}

This command might take sometime to run, be patient.

This outputs something like the below:

The command generates a number of new files and folders for us:

{color:#191918;}
bc. {color:#191918;}codecraft
// production or development builds of our applicaiton go here.
├── dist

// main application code goes here.
├── src
│   ├── app
│   │   ├── app.component.css
│   │   ├── app.component.html
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   ├── app.module.ts
│   │   ├── index.ts
│   │   └── shared
│   │   └── index.ts

// settings for the different environments, dev, qa, prod.
│   ├── environments
│   │   ├── environment.prod.ts
│   │   └── environment.ts

// main html and typescript file
│   ├── index.html
│   ├── main.ts

│   ├── favicon.ico
│   ├── polyfills.ts
│   ├── styles.css
// prepares test environment and runs all the unit tests
│   ├── test.ts

// typescript configuration file
│   ├── tsconfig.json

// typescript type definition file
│   └── typings.d.ts

// The E2E tests for our application go here
├── e2e

├── angular-cli.json
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── README.md
└── tslint.jsonpre

{background:none;}

The directory structure follows the recommended app structure and style guide.

As well as creating the files and folders for us; we can see from
bc. {color:#191918;}package.json that it installed the correct versions of all the required npm dependencies for us also.

{color:#191918;}
bc. {color:#191918;}{
  "name": "codecraft",
  "version": "0.0.0",
  "license": "MIT",
  "angular-cli": {},
  "scripts": {
    "start": "ng serve",
    "lint": "tslint \"src//*.ts\"",
    "test": "ng test",
    "pree2e": "webdriver-manager update",
    "e2e": "protractor"
  },
  "private": true,
  "dependencies": {
    "@angular/common": "~2.1.0",
    "@angular/compiler": "~2.1.0",
    "@angular/core": "~2.1.0",
    "@angular/forms": "~2.1.0",
    "@angular/http": "~2.1.0",
    "@angular/platform-browser": "~2.1.0",
    "@angular/platform-browser-dynamic": "~2.1.0",
    "@angular/router": "~3.1.0",
    "@types/moment": "^2.13.0",
    "core-js": "^2.4.1",
    "moment": "^2.15.2",
    "rxjs": "5.0.0-beta.12",
    "ts-helpers": "^1.1.1",
    "zone.js": "^0.6.23"
  },
  "devDependencies": {
    "@types/jasmine": "^2.2.30",
    "@types/node": "^6.0.42",
    "angular-cli": "1.0.0-beta.18",
    "codelyzer": "1.0.0-beta.1",
    "jasmine-core": "2.4.1",
    "jasmine-spec-reporter": "2.5.0",
    "karma": "1.2.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-cli": "^1.0.1",
    "karma-jasmine": "^1.0.2",
    "karma-remap-istanbul": "^0.2.1",
    "protractor": "4.0.9",
    "ts-node": "1.2.1",
    "tslint": "3.13.0",
    "typescript": "~2.0.3"
  }
}pre

So far in this course we have bundled all our code into one file on plunker for convenience.

Lets see how the Angular CLI breaks up the code into multiple files and where those files are located.

{color:#191918;}
{color:#191918;}
src/app/app.component.ts

{color:#191918;} The new project is bootstrapped with one component, our root component which it called bc. {color:#191918;}AppComponent and has a selector of bc. {color:#191918;}app-root.

Listing 1. src/app/app.component.ts

{color:#191918;}
bc. {color:#191918;}import { Component } from '@angular/core';

@Component({ selector: ‘app-root’, templateUrl: ‘./app.component.html’, styleUrls: [‘./app.component.css’]
})
export class AppComponent { title = ‘app works hey!’;
}pre

{color:#191918;}
{color:#191918;}
src/index.html

{color:#191918;}
{color:#191918;}app-root component has been added to our
bc. {color:#191918;}index.html file already.

There are no script tags present yet, that’s fine the angular build process adds all the required script and link tags for us.

Listing 2. src/index.html

{color:#191918;}
bc. {color:#191918;}<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Codecraft</title>
  <base href="/">
Loading… pre

{color:#191918;}
{color:#191918;}
src/app/app.module.ts

{color:#191918;} Our top level module configuration is stored in this file.
{color:#191918;}
bc. {color:#191918;}import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from ‘./app.component’;
import { HeaderComponent } from ‘./header/header.component’;
import { LoginButtonComponent } from ‘./header/login-button/login-button.component’;
import { MyDirective } from ‘./my.directive’;
import { MyPipe } from ‘./my.pipe’;

@NgModule({ declarations: [ // AppComponent, // HeaderComponent, // LoginButtonComponent, // MyDirective, // MyPipe ], imports: [ BrowserModule, FormsModule, HttpModule ], providers: [], bootstrap: [AppComponent]
})
export class AppModule { }pre

{color:#191918;}
{color:#191918;}
src/main.ts

{color:#191918;} The actual act of importing our main module and boostrapping our Angular web application is left to the bc. {color:#191918;}main.ts file.
{color:#191918;}
bc. {color:#191918;}import './polyfills.ts';

import { platformBrowserDynamic } from ‘@angular/platform-browser-dynamic’;
import { enableProdMode } from ‘@angular/core’;
import { environment } from ‘./environments/environment’;
import { AppModule } from ‘./app/’;

if (environment.production) { enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

Serve an application with
bc. {color:#191918;}ng serve

With the CLI we can also easily serve our application using a local web-server.

We just run:

{color:#191918;}
bc. {color:#191918;}ng servepre

This builds our application, bundles all our code using webpack and makes it all available through
bc. {color:#191918;}localhost:4200.

{color:#191918;}ng serve also watches for any changes to files in our project and auto-reloads the browser for us.

The command runs the application through a web-server that support HTML5 push-state routing.

{background:none;}

The above will make sense once we cover Routing later on in this book.

Generate code with
bc. {color:#191918;}ng generate

The ability to generate stub code is one of the most useful features of the CLI.

The most exciting part of this is that it automatically generates code that adheres to the official style guide.

{background:none;}

Projects built using the Angular CLI should look like each other. Developers who are used to the way Angular CLI generates files are going to find it easier to work on multiple different projects, as long as they all use the Angular CLI.

With the generate command we can create new components, directives, routes not available in version 1.0.0-beta.15, pipes, services, classes, interfaces and enums.

Each of the above types of things it can create is called a scaffold.

We can run this command using
bc. {color:#191918;}ng generate 

If we wanted to generate a component called
bc. {color:#191918;}HeaderComponent we would write:

{color:#191918;}
bc. {color:#191918;}ng generate component Headerpre

This creates a number of files in a folder called
bc. {color:#191918;}header in
bc. {color:#191918;}src/app, like so:

{color:#191918;}
bc. {color:#191918;}app
├── header
│   ├── header.component.css // The css for this component
│   ├── header.component.html // The template for this component
│   ├── header.component.spec.ts // The unit test for this component
│   └── header.component.ts // The component typescript filepre

Taking a look at
bc. {color:#191918;}header.component.ts:

{color:#191918;}
bc. {color:#191918;}import { Component, OnInit } from '@angular/core';

@Component({ selector: ‘app-header’, templateUrl: ‘./header.component.html’, styleUrls: [‘./header.component.css’]
})
export class HeaderComponent implements OnInit {

constructor() { } ngOnInit() { }

}pre

{background:none;}

Don’t name your component
bc. {color:#191918;}HeaderComponent. Angular CLI automatically appends
bc. {color:#191918;}Component to the name, so you component class would end up being
bc. {color:#191918;}HeaderComponentComponent.

The command above can be shortened to:

{color:#191918;}
bc. {color:#191918;}ng g c Headerpre

{background:none;}

If we run the command in an app folder, the
bc. {color:#191918;}generate command will create files relative to the current folder you are in. So if we are in
bc. {color:#191918;}src/app/header and we run
bc. {color:#191918;}ng g c LoginButton it will generate the files in
bc. {color:#191918;}src/app/header/login-button/

We can also be explicit about where we want the generated files to go by running
bc. {color:#191918;}ng g component ./src/app/foo/bar this will create a component called
bc. {color:#191918;}BarComponent in the folder
bc. {color:#191918;}./src/app/foo/bar.

Available Scaffolds

{color:#191918;}
{color:#191918;}
Component

{color:#191918;}
bc. {color:#191918;}ng g component My // Creates MyComponentpre

By default all generated files go in into
bc. {color:#191918;}src\app\my-component, a folder called
bc. {color:#191918;}my-component is created for us.

{color:#191918;}
{color:#191918;}
Directive

{color:#191918;}
bc. {color:#191918;}ng g directive My // Creates MyDirectivepre

By default all generated files go in into
bc. {color:#191918;}src\app, no folder is created.

{color:#191918;}
{color:#191918;}
Pipe

{color:#191918;}
bc. {color:#191918;}ng g pipe My // Creates MyPipepre

By default all generated files go in into
bc. {color:#191918;}src\app, no folder is created.

{color:#191918;}
{color:#191918;}
Service

{color:#191918;}
bc. {color:#191918;}ng g service MyService // Creates MyServicepre

By default all generated files go in into
bc. {color:#191918;}src\app, no folder is created.

{color:#191918;}
{color:#191918;}
Class

{color:#191918;}
bc. {color:#191918;}ng g class MyClass // Creates MyClasspre

By default all generated files go in into
bc. {color:#191918;}src\app, no folder is created.

{color:#191918;}
{color:#191918;}
Interface

{color:#191918;}
bc. {color:#191918;}ng g interface MyInterface // Creates MyInterfacepre

By default all generated files go in into
bc. {color:#191918;}src\app, no folder is created.

{color:#191918;}
{color:#191918;}
Enum

{color:#191918;}
bc. {color:#191918;}ng g enum MyEnum // Creates MyEnumpre

By default all generated files go in into
bc. {color:#191918;}src\app, no folder is created.

Create a build with
bc. {color:#191918;}ng build

The
bc. {color:#191918;}ng serve command does a great job of enabling development locally.

However eventually we will want some code which we can host on another server somewhere.

The Angular CLI again has us covered in this regard, if we want to create a development build we simply type

{color:#191918;}
bc. {color:#191918;}ng buildpre

This bundles all our javascript, css, html into a smaller set of files which we can host on another site simply.

It outputs these files into the
bc. {color:#191918;}dist folder:

{color:#191918;}
bc. {color:#191918;}.
├── assets
├── index.html
├── inline.js
├── inline.map
├── main.bundle.js
├── main.map
├── styles.bundle.js
└── styles.mappre

To serve our built application site we just need to serve this folder. For example if using python we could simply run
bc. {color:#191918;}python -m SimpleHTTPServer from the
bc. {color:#191918;}dist folder and view the application from
bc. {color:#191918;}0.0.0.0:8000.

Production Builds

By default the
bc. {color:#191918;}ng build command creates a development build, no effort is made to optimise the code.

To create a production build we just run

{color:#191918;}
bc. {color:#191918;}ng build --prodpre

This might generate an output like the below:

{color:#191918;}
bc. {color:#191918;}.
├── assets
├── index.html
├── inline.js
├── main.3f26904b701596b6d90a.bundle.js
├── main.3f26904b701596b6d90a.bundle.js.gz
└── styles.b52d2076048963e7cbfd.bundle.jspre

Running with
bc. {color:#191918;}—prod changes a few things:

{color:#191918;}

  • {color:#191918;}
    The bundles now have random strings appended to them to enable cache busting.

This ensures that a browser doesn’t try to load up previously cached versions of the files and instead load the new ones from the server.

  • {color:#191918;}
    The file sizes are much smaller. The files have been processed through a minifier and uglifier.
  • {color:#191918;}
    There is a much small
    bc. {color:#191918;}.gz file, this is a compressed version of the equivalent javascript file.

Browsers will automatically try to download the
bc. {color:#191918;}.gz version of files if they are present.

Adding a third party module

The build system simplifies the process of serving and releasing your application considerably. It works only because Angular knows about all the files used by your application.

So when we include 3rd party libraries into our application we need to do so in such a way that Angular knows about the libraries and includes them in the build process.

Bundled with the main application javascript files

If we want to include a module to use in our Angular javascript code, perhaps we want to to use the moment.js library, we just need to install it via npm like so:

{color:#191918;}
bc. {color:#191918;}npm install moment --savepre

If we also want to include the typescript type definition file for our module we can install it via:

{color:#191918;}
bc. {color:#191918;}npm install @types/moment --savepre

Now when Angular create a build either when releasing or serving locally, the moment library is automatically added to the bundle.

Global Library Installation

Some javascript libraries need to be added to the global scope, and loaded as if they were in a script tag.

We can do this by editing the
bc. {color:#191918;}angular-cli.json file in our project root.

The twitter bootstrap library is a great example of this, we need to incldue css and script files in the global scope.

First we install the bootstrap library via npm like so:

{color:#191918;}
bc. {color:#191918;}npm install [email protected]

Then we add the required javascript files to the
bc. {color:#191918;}app.scripts section or the
bc. {color:#191918;}app.styles in
bc. {color:#191918;}angular-cli.json like so:

{color:#191918;}
bc. {color:#191918;}{
  .
  .
  .
  "apps": [
    {
      .
      .
      .
      "styles": [
        "styles.css",
        "../node_modules/bootstrap/dist/css/bootstrap.css"
      ],
      "scripts": [
        "../node_modules/jquery/dist/jquery.js",
        "../node_modules/tether/dist/js/tether.js",
        "../node_modules/bootstrap/dist/js/bootstrap.js"
      ],
      .
      .
      .
    }
  ],
  .
  .
  .
}pre

Now when the build runs the CLI includes those files in the bundle and injects then in the global scope.

Testing Angular

Angular has always been synonymous with testing and so there should be no surprise that the command line tool comes with features to make Angular testing easier.

The default mechanism for unit testing in Angular is via jasmine and karma.

Whenever we generate code via scaffolds it also generates a
bc. {color:#191918;}.spec.ts. The code the CLI bootstraps inside this file depends on the scaffold type but essentially is a jasmine test spec which you can flesh out with more test cases.

{background:none;}

These types of tests are called unit tests because we should be writing the tests so we only test one unit of code and each test case is independent of the others.

We can run all our unit tests with one command:

{color:#191918;}
bc. {color:#191918;}ng testpre

This builds our project and then runs all the tests, any errors are output to the terminal.

This command also watches for any changes in our files and, if it detects any, re-runs the tests automatically.

{background:none;}

When running the tests it opens up a browser window like the example above.

It needs this browser windows to run the tests, do not close it!

Summary

The above is just an overview of the main commands and their default features.

To find out more details about each command and how we can customise the behaviour via flags we can run
bc. {color:#191918;}ng help in the terminal.

By handling the setup for us the CLI has made working with Angular 2 much easier.

By standardising setup and structure it’s also made Angular projects fungible. Angular developers used to the Angular CLI should feel comfortable on all Angular CLI projects and be able to hit the floor running.

ACTIVITY

In this activity you will re-create the Joke application we’ve ran using Plunker as an Angular CLI project instead.

Steps

{color:#191918;}

  1. {color:#191918;}
    Ensure you have node installed on your computer. If you are unsure how to install node then follow the instructions in the Node lecture in the Appendix to this course.
  1. {color:#191918;}
    Follow the instructions in the previous lectures and on the Angular CLI repository site to install the Angular CLI on your computer.
  1. {color:#191918;}
    Crete a project locally on your computer.
  1. {color:#191918;}
    Mirror the functionality of the Joke application in the plunker below in your Angular CLI powered project.

http://plnkr.co/edit/b0F6Dhb40Hm5zfiamAix?p=preview

Solution

When you are ready compare your answer to the solution in this repository: https://github.com/codecraftpro/angular-2-book-cli-activity

OVERVIEW

Components are the fundamental building block of Angular applications.

Components are composable, we can build larger Components from smaller ones.

An Angular application is therefore just a tree of such Components, when each Component renders, it recursively renders its children Components.

At the root of that tree is the top level Component, the root Component.

When we bootstrap an Angular application we are telling the browser to render that top level root Component which renders it’s child Components and so on.

In this section we build upon the knowledge learned in the quickstart and cover:

{color:#191918;}

  • {color:#191918;}
    How to architect an application using Components.
  • {color:#191918;}
    The Component decorator in more depth.
  • {color:#191918;}
    Content Projection
  • {color:#191918;}
    Component Lifecycle Hooks
  • {color:#191918;}
    View Children vs. Content Children

ARCHITECTING WITH COMPONENTS

Learning Objectives

{color:#191918;}

  • {color:#191918;}
    Know how to architect an angular Application.

Process

When building a new Angular application, we start by:

{color:#191918;}

  1. {color:#191918;}
    Breaking down an applications into seperate Components.
  1. {color:#191918;}
    For each component we describe it’s resonsibilities.
  1. {color:#191918;}
    Once we’ve desribed the responsibilites we then describe it’s inputs & outputs, it’s public facing interface.

Take for instance this simple example.

We have a basic application with a Header, Sidebar and Content area, we would implement each of these as their own Component. The next stage is for each component to list out the responsibilities, inputs and outputs, like so:

{color:#191918;}
{color:#191918;}
HeaderComponent

{color:#191918;}

{color:#191918;}
{color:#191918;}
Responsibilities

{color:#191918;} All aspects of authentication. Letting the user login/signup and logout.

{color:#191918;}
Inputs

{color:#191918;} None

{color:#191918;}
Outputs

{color:#191918;}

{color:#191918;}

  • {color:#191918;}
{color:#191918;}LoginChanged - An output event that is fired when the users login state changes.

{color:#191918;}
SidebarComponent

{color:#191918;}

{color:#191918;}
{color:#191918;}
Responsibilities

{color:#191918;} Performing searches

{color:#191918;}
Inputs

{color:#191918;} None

{color:#191918;}
Outputs

{color:#191918;}

{color:#191918;}

  • {color:#191918;}
{color:#191918;}SearchTermChanged - An output event that is fired when a user performs a search,
bc. {color:#191918;}$event contains the search term.

{color:#191918;}
ContentComponent

{color:#191918;}

{color:#191918;}
{color:#191918;}
Responsibilities

{color:#191918;} Showing the search results.

{color:#191918;}
Inputs

{color:#191918;}

{color:#191918;}

  • {color:#191918;}
{color:#191918;}SearchTerm the search term that we want to filter the results by.

{color:#191918;}
Outputs

{color:#191918;} None

{background:none;}

Listing the inputs and outputs and what area this Component is responsible for helps to ensure the Components are architected correctly. The goal is for each Component to have a well defined boundary.

Data Flow

When we link up the Components above with our applications root Component the flow of data between all the inputs and outputs might look something like this:

The actual binding of inputs and outputs happens in HTML, in the templates of Components. The template for our root Component might end up looking like so:

{color:#191918;}
bc. {color:#191918;}<header (loginChanged)="loggedIn = $event"></header>
<sidebar (searchTermChanged)="searchTerm = $event"></sidebar>
<content [searchTerm]="searchTerm"></content>pre

Data flow describes how we glue Components together through their inputs and outputs.

Closely looking at the diagram above an interesting fact occurs; with one way data binding, inputs go down the tree, outputs go up the tree. With one way data binding reasoning about your application becomes a lot simpler, we can trace through the flow of events in our application easily.

Summary

Architecting an Angular application means understanding that it’s just a tree of Components, each Component has some inputs and outputs and should have a clear responsibility with respect to the rest of the application.

Components are composable, so we might go a step further and include a
bc. {color:#191918;}LoginButtonComponent in our
bc. {color:#191918;}HeaderComponent. But only if we would want to re-use the
bc. {color:#191918;}LoginButtonComponent independently of the
bc. {color:#191918;}HeaderComponent.

TEMPLATES, STYLES & VIEW ENCAPSULATION

Learning Objectives

We’ve covered the basics of the
bc. {color:#191918;}@Component decorator in the quickstart. We explained how decorators work and both the
bc. {color:#191918;}template and
bc. {color:#191918;}selector configuration properties of the
bc. {color:#191918;}@Component decorator.

In this lecture we will go through a number of other configuration properties including
bc. {color:#191918;}templateUrl,
bc. {color:#191918;}styles,
bc. {color:#191918;}styleUrls and
bc. {color:#191918;}encapsulation.

In the section on Dependency Injection we will cover two other ways of configuring Components with the
bc. {color:#191918;}providers and
bc. {color:#191918;}viewProviders properties.

templateURL

We don’t have to write our template code inline with our component code. We can store our HTML template files separately and just refer to them in our component by using the
bc. {color:#191918;}templateUrl property.

Using the joke application we built in the quickstart, lets move the template for the
bc. {color:#191918;}JokeFormComponent to a file called
bc. {color:#191918;}joke-form-component.html, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-form',
  templateUrl: 'joke-form-component.html' [_{color:#468C54;}①_]
})
class JokeFormComponent {
  @Output() jokeCreated = new EventEmitter<Joke>();
createJoke(setup: string, punchline: string) { this.jokeCreated.emit(new Joke(setup, punchline)); } }pre

{color:#191918;}

  1. {color:#191918;} We point our component to an external template file by using the
    bc. {color:#191918;}templateUrl property.

styles

We can also specify any custom css styles for our component with the
bc. {color:#191918;}styles property.

{color:#191918;}styles takes an [_array of strings_] and just like
bc. {color:#191918;}template we can use multi-line strings with back-ticks.

Let’s define a style for the
bc. {color:#191918;}JokeFormComponent so it gives it a background color of gray.

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-form',
  template: 'joke-form-component.html',
  styles: [
    `
    .card {
      background-color: gray;
    }
    `
  ],
})
class JokeFormComponent {
  @Output() jokeCreated = new EventEmitter<Joke>();
createJoke(setup: string, punchline: string) { this.jokeCreated.emit(new Joke(setup, punchline)); } }pre

{background:none;}

The
bc. {color:#191918;}styles property above takes an array of strings, each string can contain any number of CSS declarations.

The form component in our application now turns gray, like so:

View Encapsulation

Even though we changed the background color of
bc. {color:#191918;}.card and we have multiple cards on the page only the form component card was rendered with a gray background.

Normally if we change a css class the effect is seen throughout an application, something special is happening here and it’s called View Encapsulation.

Angular is inspired from Web Components, a core feature of which is the shadow DOM.

The shadow DOM lets us include styles into Web Components without letting them leak outside the component’s scope.

Angular also provides this feature for Components and we can control it with the
bc. {color:#191918;}encapsulation property.

The valid values for this config property are:

{color:#191918;}

  • {color:#191918;}
{color:#191918;}ViewEncapsulation.Native
  • {color:#191918;}
{color:#191918;}ViewEncapsulation.Emulated
  • {color:#191918;}
{color:#191918;}ViewEncapsulation.None.

The default value is
bc. {color:#191918;}ViewEncapsulation.Emulated and that is the behaviour we are currently seeing.

ViewEncapsulation.Emulated

Let’s inspect the form element with our browsers developer tools to investigate what’s going on.

By looking at the DOM for our
bc. {color:#191918;}JokeFormComponent we can see that Angular added some automatically generated attributes, like so.

Specifically it added an attribute called
bc. {color:#191918;}_ngcontent-qwe-3.

The other components on the page don’t have these automatically generated attributes, only the
bc. {color:#191918;}JokeFormComponent which is the only component where we specified some styles.

Again by looking at the styles tab in our developer tools we can see a style is set for
bc. {color:#191918;}_ngcontent-qwe-3 like so:

{background:none;}

The css selector
bc. {color:#191918;}.cardngcontent-qwe-3] targets [_only the
bc. {color:#191918;}JokeFormComponent since that is the only component with a html attribute of
bc. {color:#191918;}_ngcontent-qwe-3.

In the
bc. {color:#191918;}ViewEncapsulation.Emulated mode Angular changes our generic css class selector to one that target just a single component type by using automatically generated attributes.

This is the reason that only the
bc. {color:#191918;}JokeFormComponent is gray despite the fact that we use the same card class for all the other
bc. {color:#191918;}JokeComponents as well.

Any styles we define on a component don’t leak out to the rest of the application but with
bc. {color:#191918;}ViewEncapsulation.Emulated our component still inherits global styles from twitter bootstrap.

Our
bc. {color:#191918;}JokeFormComponent still gets the global card styles from twitter bootstrap and the encapsulated style from the component itself.

ViewEncapsulation.Native

If we want Angular to use the shadow DOM we can set the encapsulation parameter to use
bc. {color:#191918;}ViewEncapsulation.Native like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-form',
  templateUrl: 'joke-form-component.html',
  styles: [
    `
    .card {
      background-color: gray;
    }
    `
  ],
  encapsulation: ViewEncapsulation.Native # <!>
})
class JokeFormComponent {
  @Output() jokeCreated = new EventEmitter<Joke>();
createJoke(setup: string, punchline: string) { this.jokeCreated.emit(new Joke(setup, punchline)); } }pre

But now if we look at the application although the background color of the
bc. {color:#191918;}JokeFormComponent is still gray, we’ve lost the global twitter bootstrap styles.

With
bc. {color:#191918;}ViewEncapsulation.Native styles we set on a component do not leak outside of the components scope. The other cards in our application do not have a gray background despite the fact they all still use the card class.

This is great if we are defining a 3rd party component which we want people to use in isolation. We can describe the look for our component using css styles without any fear that our styles are going to leak out and affect the rest of the application.

However with
bc. {color:#191918;}ViewEncapsulation.Native our component is also isolated from the global styles we’ve defined for our application. So we don’t inherit the twitter bootstrap styles and have to define all the required styles on our component decorator.

Finally
bc. {color:#191918;}ViewEncapsulation.Native requires a feature called the shadow DOM which is not supported by all browsers.

ViewEncapsulation.None

And If we don’t want to have any encapsulation at all, we can use
bc. {color:#191918;}ViewEncapsulation.None.

The resulting application looks like so:

By doing this all the cards are now gray.

If we investigate with our browser’s developer tools we’ll see that Angular added the
bc. {color:#191918;}.card class as a global style in the head section of our HTML.

We are not encapsulating anything, the style we defined in our card form component has leaked out and started affecting the other components.

styleURLs

Like the
bc. {color:#191918;}templateUrl property, with the
bc. {color:#191918;}styleUrls property we can externalise the css for our component into another file and include it in.

However like the
bc. {color:#191918;}styles parameter, the
bc. {color:#191918;}styleUrls param takes an array of css files, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-form',
  templateUrl: 'joke-form-component.html',
  styleUrls: [
          'joke-form-component.css'
  ]
})
class JokeFormComponent {
  @Output() jokeCreated = new EventEmitter<Joke>();
createJoke(setup: string, punchline: string) { this.jokeCreated.emit(new Joke(setup, punchline)); } }pre

Depreciated Properties

{background:none;}

If you have seen code that discusses the additional
bc. {color:#191918;}@Component properties;
bc. {color:#191918;}directives,
bc. {color:#191918;}pipes,
bc. {color:#191918;}inputs and
bc. {color:#191918;}outputs these were in the beta version of Angular and were removed in the final 2.0 release. So the information you’ve read is unfortunately outdated.

Summary

We can externalise our HTML template into a separate file and include it in with the
bc. {color:#191918;}templateUrl property.

We can also define styles for our component via the
bc. {color:#191918;}styles and
bc. {color:#191918;}styleUrls property.

By default styles for our components are encapsulated, that means that they don’t leak out and affect the rest of the application.

We can explicitly set the encapsulation strategy using the
bc. {color:#191918;}encapsulation property.

By default, the renderer uses ViewEncapsulation.Emulated if the view has styles, otherwise ViewEncapsulation.None. There is also a ViewEncapsulation.Native method which uses the shadow DOM to encapsulate the view.

Listing

http://plnkr.co/edit/2MUcs44WUo2G1cS2JvX4?p=preview

Listing 1. index.html

{color:#191918;}
bc. {color:#191918;}<!DOCTYPE html>
<!--suppress ALL -->
<html>
<head>
  <link rel="stylesheet"
        href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css">

Loading…

pre

Listing 2. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {Component, NgModule, Input, Output, EventEmitter, ViewEncapsulation} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

class Joke { public setup: string; public punchline: string; public hide: boolean;

constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }

@Component({ selector: ‘joke-form’, templateUrl: ‘joke-form-component.html’, styleUrls: [ ‘joke-form-component.css’ ], encapsulation: ViewEncapsulation.Emulated // encapsulation: ViewEncapsulation.Native // encapsulation: ViewEncapsulation.None

})
class JokeFormComponent { @Output() jokeCreated = new EventEmitter();

createJoke(setup: string, punchline: string) { this.jokeCreated.emit(new Joke(setup, punchline)); } }

Component({ selector: 'joke', template: ` <div class="card card-block"> <h4 class="card-title">{{data.setup}}</h4> <p class="card-text" [hidden]="data.hide">{{data.punchline}}</p> <a (click)="data.toggle()" class="btn btn-warning">Tell Me </a> </div> ` }) class JokeComponent { Input(‘joke’) data: Joke;
}

@Component({ selector: ‘joke-list’, template: `

`
})
class JokeListComponent { jokes: Joke[];

constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror?”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse?”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } addJoke(joke) { this.jokes.unshift(joke); } }

@Component({ selector: ‘app’, template: `
`
})
class AppComponent {
}

@NgModule({ imports: [BrowserModule], declarations: [ AppComponent, JokeComponent, JokeListComponent, JokeFormComponent ], bootstrap: [AppComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

Listing 3. joke-form-component.css

{color:#191918;}
bc. {color:#191918;}.card {
  background-color: gray;
}pre

Listing 4. joke-form-component.html

{color:#191918;}
bc. {color:#191918;}<div class="card card-block">
  <h4 class="card-title">Create Joke</h4>
  <div class="form-group">
    <input type="text"
           class="form-control"
           placeholder="Enter the setup"
           #setup>
  </div>
  <div class="form-group">
    <input type="text"
           class="form-control"
           placeholder="Enter the punchline"
           #punchline>
  </div>
  <button type="button"
          class="btn btn-primary"
          (click)="createJoke(setup.value, punchline.value)">Create
  </button>
</div>pre

CONTENT PROJECTION

Goals

Change our application so that a developer who is re-using our
bc. {color:#191918;}JokeComponent can also configure how a joke will be rendered on the screen.

Learning Objectives

{color:#191918;}

  • {color:#191918;}
    What is content projection and why might we want to use it.
  • {color:#191918;}
    How to project content using the
    bc. {color:#191918;}ng-content tag.
  • {color:#191918;}
    How to project multiple pieces of content using css selectors.

Motivation

Lets say someone else wanted to use our
bc. {color:#191918;}JokeComponent but instead of displaying the punchline in a
bc. {color:#191918;}

 tag they wanted to display it in a larger
bc. {color:#191918;}

 tag.

Our component right now doesn’t let itself be reused like that.

However we can design our component with something called content projection to enable it to be customised by the component or developer who is using it.

Content projection

If we add the tag
bc. {color:#191918;} anywhere in our template HTML for our component. The inner content of the tags that define our component are then projected into this space.

So if we changed the template for our
bc. {color:#191918;}JokeComponent to be something like:

{color:#191918;}
bc. {color:#191918;}<div class="card card-block">
  <h4 class="card-title">{{ data.setup }}</h4>
  <p class="card-text"
     [hidden]="data.hide">
    <ng-content></ng-content> [_{color:#468C54;}①_]
  </p>
  <a class="btn btn-primary"
     (click)="data.toggle()">Tell Me
  </a>
</div>pre

{color:#191918;}

  1. {color:#191918;} We’ve replaced
    bc. {color:#191918;}{{data.punchline}} with
    bc. {color:#191918;}

Then if we changed our
bc. {color:#191918;}JokeListComponent template from this:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes" [joke]="j"></joke>pre

To this:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes" [joke]="j">
  <h1>{{ j.punchline }}</h1> [_{color:#468C54;}①_]
</joke>pre

{color:#191918;}

  1. {color:#191918;} In-between the opening and closing
    bc. {color:#191918;}joke tags we’ve added some HTML to describe how we want the punchline to be presented on the screen, with a
    bc. {color:#191918;}

     tag.

The
bc. {color:#191918;}

{{ j.punchline }}

 defined in the parent
bc. {color:#191918;}JokeListComponent, replaces the
bc. {color:#191918;} tag in the
bc. {color:#191918;}JokeComponent.

This is called Content Projection we project content from the parent Component to our Component.

If we create our components to support content projection then it enables the consumer of our component to configure exactly how they want the component to be rendered.

The downside of content projection is that the
bc. {color:#191918;}JokeListComponent doesn’t have access to the properties or methods on the JokeComponent.

So the content we are projecting we can’t bind to properties or methods of our
bc. {color:#191918;}JokeComponent, only the
bc. {color:#191918;}JokeListComponent.

Multi-content projection

What if we wanted to define multiple content areas, we’ve got a setup and a punchline lets make both of those content projectable.

Specifically want the setup line to always end with a
bc. {color:#191918;}? character.

{background:none;}

We are using this example for demonstration purposes only. This problem could easily be solved in a number of other ways, all of them easier than using content projection.

We might change our
bc. {color:#191918;}JokeListComponent template to be something like:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes" [joke]="j">
  <span>{{ j.setup }} ?</span>
  <h1>{{ j.punchline }}</h1> [_{color:#468C54;}①_]
</joke>pre

But in our JokeComponent template we can’t simply add two
bc. {color:#191918;} tags, like so:

{color:#191918;}
bc. {color:#191918;}<div class="card card-block">
  <h4 class="card-title">
    <ng-content></ng-content>
  </h4>
  <p class="card-text"
     [hidden]="data.hide">
    <ng-content></ng-content>
  </p>
  <a class="btn btn-primary"
     (click)="data.toggle()">Tell Me
  </a>
</div>pre

Angular doesn’t know which content from the parent
bc. {color:#191918;}JokeListComponent to project into which
bc. {color:#191918;}ng-content tag in
bc. {color:#191918;}JokeComponent.

To solve this
bc. {color:#191918;}ng-content has another attribute called
bc. {color:#191918;}select.

If you pass to
bc. {color:#191918;}select a css matching selector, it will extract only the elements matching the selector from the passed in content to be projected.

Let’s explain with an example:

{color:#191918;}
bc. {color:#191918;}<div class="card card-block">
  <h4 class="card-title">
    <ng-content select="span"></ng-content> [_{color:#468C54;}①_]
  </h4>
  <p class="card-text"
     [hidden]="data.hide">
    <ng-content select="h1"></ng-content> [_{color:#468C54;}②_]
  </p>
  <a class="btn btn-primary"
     (click)="data.toggle()">Tell Me
  </a>
</div>pre

{color:#191918;}

  1. {color:#191918;}
    bc. {color:#191918;} will match
    bc. {color:#191918;}{{ j.setup }} ?.
  1. {color:#191918;}
    bc. {color:#191918;} will match
    bc. {color:#191918;}

    {{ j.punchline }}

    .

That however can be a bit tricky to manage, lets use some more meaningful rules matching perhaps by class name.

{color:#191918;}
bc. {color:#191918;}<div class="card card-block">
  <h4 class="card-title">
    <ng-content select=".setup"></ng-content> [_{color:#468C54;}①_]
  </h4>
  <p class="card-text"
     [hidden]="data.hide">
    <ng-content select=".punchline"></ng-content> [_{color:#468C54;}②_]
  </p>
  <a class="btn btn-primary"
     (click)="data.toggle()">Tell Me
  </a>
</div>pre

To support this lets change our parent components content to identify the different elements by classnames, like so:

{color:#191918;}
bc. {color:#191918;}<joke *ngFor="let j of jokes" [joke]="j">
  <span class="setup">{{ j.setup }} ?</span>
  <h1 class="punchline">{{ j.punchline }}</h1> [_{color:#468C54;}①_]
</joke>pre

Summary

Sometimes the nature of a component means that the consumer would like to customise the view, the presentation of data, in a unique way for each use case.

Rather than trying to predict all the different configuration properties to support all the use cases we can instead use content projection. Giving the consumer the power to configure the presentation of the component as they want.

Listing

http://plnkr.co/edit/g5nuoD8m4e1tTp7gDW4N?p=preview

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {Component, NgModule, Input, Output, EventEmitter, ViewEncapsulation} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

class Joke { public setup: string; public punchline: string; public hide: boolean;

constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }

@Component({ selector: ‘joke-form’, templateUrl: ‘joke-form-component.html’, styleUrls: [ ‘joke-form-component.css’ ], encapsulation: ViewEncapsulation.Emulated // encapsulation: ViewEncapsulation.Native // encapsulation: ViewEncapsulation.None

})
class JokeFormComponent { @Output() jokeCreated = new EventEmitter();

createJoke(setup: string, punchline: string) { this.jokeCreated.emit(new Joke(setup, punchline)); } }

Component({ selector: 'joke', template: ` <div class="card card-block"> <h4 class="card-title"> <ng-content select=".setup"></ng-content> </h4> <p class="card-text" [hidden]="data.hide"> <ng-content select=".punchline"></ng-content> </p> <a class="btn btn-primary" (click)="data.toggle()">Tell Me </a> </div> ` }) class JokeComponent { Input(‘joke’) data: Joke;
}

@Component({ selector: ‘joke-list’, template: `

{{ j.setup }}?

{{ j.punchline }}


`
})
class JokeListComponent { jokes: Joke[];

constructor() { this.jokes = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”), new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”), ]; } addJoke(joke) { this.jokes.unshift(joke); } }

@Component({ selector: ‘app’, template: `
`
})
class AppComponent {
}

@NgModule({ imports: [BrowserModule], declarations: [ AppComponent, JokeComponent, JokeListComponent, JokeFormComponent ], bootstrap: [AppComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

LIFECYCLE HOOKS

Learning Objectives

{color:#191918;}

  • {color:#191918;}
    Understand the different phases an Angular component goes through from being created to being destroyed.
  • {color:#191918;}
    Know how to hook into those phases and run your own code.
  • {color:#191918;}
    Know the order in which the different phases happen and what triggers each phase.

Phases

A component in Angular has a life-cycle, a number of different phases it goes through from birth to death.

We can hook into those different phases to get some pretty fine grained control of our application.

To do this we add some specific methods to our component class which get called during each of these life-cycle phases, we call those methods hooks.

The hooks are executed in this order:

These phases are broadly split up into phases that are linked to the component itself and phases that are linked to the children of that component.

Hooks for the component

{color:#191918;}
{color:#191918;}
constructor

{color:#191918;} This is invoked when Angular creates a component or directive by calling bc. {color:#191918;}new on the class.

{color:#191918;}
ngOnChanges

{color:#191918;} Invoked every time there is a change in one of th input properties of the component.

{color:#191918;}
ngOnInit

{color:#191918;} Invoked when given component has been initialized.

This hook is only called once after the first
bc. {color:#191918;}ngOnChanges

{color:#191918;}
ngDoCheck

{color:#191918;} Invoked when the change detector of the given component is invoked. It allows us to implement our own change detection algorithm for the given component.

{background:none;}

{color:#191918;}ngDoCheck and
bc. {color:#191918;}ngOnChanges should not be implemented together on the same component.

{background:none;}

We will cover this hook in more detail in the Advanced Components section at the end of this course.

{color:#191918;}
ngOnDestroy

{color:#191918;} This method will be invoked just before Angular destroys the component.

Use this hook to unsubscribe observables and detach event handlers to avoid memory leaks.

Hooks for the components children

These hooks are only called for components and not directives.

{background:none;}

We will cover the difference between Components and Directives in the next section.

{color:#191918;}
{color:#191918;}
ngAfterContentInit

{color:#191918;} Invoked after Angular performs any content projection into the components view (see the previous lecture on Content Projection for more info).

{color:#191918;}
ngAfterContentChecked

{color:#191918;} Invoked each time the content of the given component has been checked by the change detection mechanism of Angular.

{color:#191918;}
ngAfterViewInit

{color:#191918;} Invoked when the component’s view has been fully initialized.

{color:#191918;}
ngAfterViewChecked

{color:#191918;} Invoked each time the view of the given component has been checked by the change detection mechanism of Angular.

{background:none;}

We’ll dig into the children hooks in more detail in the next lecture.

Adding hooks

In order to demonstrate how the hooks work we’ll adjust the joke application we’ve been working with so far.

Firstly lets change the
bc. {color:#191918;}JokeComponent so it hooks into all the phases.

All we need to do is to add functions to the component class matching the hook names above, like so:

{color:#191918;}
bc. {color:#191918;}class JokeComponent {
  @Input('joke') data: Joke;
constructor() { console.log(`new – data is ${this.data}`); } ngOnChanges() { console.log(`ngOnChanges – data is ${this.data}`); } ngOnInit() { console.log(`ngOnInit – data is ${this.data}`); } ngDoCheck() { console.log(“ngDoCheck”) } ngAfterContentInit() { console.log(“ngAfterContentInit”); } ngAfterContentChecked() { console.log(“ngAfterContentChecked”); } ngAfterViewInit() { console.log(“ngAfterViewInit”); } ngAfterViewChecked() { console.log(“ngAfterViewChecked”); } ngOnDestroy() { console.log(“ngOnDestroy”); } }pre

To easily trigger these hooks lets change the rest of the application. We remove the form and change the parent
bc. {color:#191918;}JokeListComponent so it has two buttons. One that adds a joke triggering Angular to create a new
bc. {color:#191918;}JokeComponent instance. Another button to clear the list of jokes triggering Angular to delete the
bc. {color:#191918;}JokeComponents.

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-list',
  template: `
<joke *ngFor="let j of jokes" [joke]="j">
  <span class="setup">{{ j.setup }} ?</span>
  <h1 class="punchline">{{ j.punchline }}</h1>
</joke>



`
})
class JokeListComponent { jokes: Joke[] = [];

addJoke() { this.jokes.unshift(new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”)); } deleteJoke() { this.jokes = [] } }pre

When we run this application we now see two buttons:

If we click “Add Joke” then a joke is added to the list and Angular creates an instance of the
bc. {color:#191918;}JokeComponent triggering the lifecycle hooks.

Looking at the console at this time we would see these logs:

{color:#191918;}
bc. {color:#191918;}new - data is undefined
ngOnChanges - data is [object Object]
ngOnInit  - data is [object Object]
ngDoCheck
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewCheckedpre

For the first 3 hooks we are also printing out the value of the components
bc. {color:#191918;}joke input property.

We can see that in the
bc. {color:#191918;}constructor the input property is undefined.

However by the time the
bc. {color:#191918;}ngOnChanges hook is called we can see that the input property is now set to the joke.

{background:none;}

The best place to initialise your components is in the
bc. {color:#191918;}ngOnInit lifecycle hook and not the constructor because only at this point have any input property bindings been processed.

The reason we use
bc. {color:#191918;}ngOnInit and not
bc. {color:#191918;}ngOnChanges to initialise a component is that
bc. {color:#191918;}ngOnInit is only called once whereas
bc. {color:#191918;}ngOnChanges is called for every change to the input properties.

When we press the Clear Jokes button, Angular deletes the
bc. {color:#191918;}JokeComponent and calls the
bc. {color:#191918;}ngOnDestroy hook which we can see in the logs like so:

{color:#191918;}
bc. {color:#191918;}ngOnDestroypre

Detecting what has changed

We can actually tap into the exact changes to the input properties by examining the first param to the
bc. {color:#191918;}ngOnChanges function, which we typically call
bc. {color:#191918;}changes.

The type of
bc. {color:#191918;}changes is a map of the input property name to an instance of
bc. {color:#191918;}SimpleChange:

{color:#191918;}
bc. {color:#191918;}class SimpleChange {
  constructor(previousValue: any, currentValue: any)
  previousValue : any
  currentValue : any
  isFirstChange() : boolean
}pre

Using the above we can find out in our
bc. {color:#191918;}ngOnChanges function which input properties changed (if we have more than one) and also what the previous and current values are.

We change our
bc. {color:#191918;}ngOnChanges function to take the
bc. {color:#191918;}changes argument and loop through it to print out the

{color:#191918;}SimpleChange.
bc. {color:#191918;}currentValue and
bc. {color:#191918;}previousValue.
{color:#191918;}
bc. {color:#191918;}ngOnChanges(changes: SimpleChanges) {
  console.log(`ngOnChanges - data is ${this.data}`);
  for (let key in changes) {
    console.log(`${key} changed.
Current: ${changes[key].currentValue}.
Previous: ${changes[key].previousValue}`);
  }
}pre

This prints out the below to the console:

{color:#191918;}
bc. {color:#191918;}ngOnChanges - data is [object Object]
data changed.
Current: [object Object].
Previous: CD_INIT_VALUEpre

The current value is the joke object that was bound to the
bc. {color:#191918;}data input property.

{background:none;}

When no value has been set for an input property it gets defaulted to the string ‘CD_INIT_VALUE’ rather than
bc. {color:#191918;}null or
bc. {color:#191918;}undefined.

Interfaces

In the sample code so far we are just defining the hook functions directly on the class, but we can take advantage of a feature of TypeScript, interfaces, and be more explicit regarding our intentions.

Each of these lifecycle hooks has an associated typescript
bc. {color:#191918;}interface of the same name but without the
bc. {color:#191918;}ng prefix. So
bc. {color:#191918;}ngOnChanges has an interface called
bc. {color:#191918;}OnChanges.

Each interface defines just one hook, by making a class implement an interface we are saying we expect the class to have implemented that member function, if it doesn’t then TypeScript should throw an error.

Adding the interfaces for our life-cycle hooks to our
bc. {color:#191918;}JokeComponent class would look something like so:

{color:#191918;}
bc. {color:#191918;}import {
    OnChanges,
    OnInit,
    DoCheck,
    AfterContentInit,
    AfterContentChecked,
    AfterViewInit,
    AfterViewChecked,
    OnDestroy
} from '@angular/core';

class JokeComponent implements OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy { …
}pre

{background:none;}

The browser based TypeScript compiler doesn’t trigger a compilation error when we don’t implement interface functions so we actually can’t see the benefit of this in the browser, but doing this using the offline local compiler will throw an error.

Summary

Using life-cycle hooks we can fine tune the behaviour of our components during creation, update and destruction.

We use the
bc. {color:#191918;}ngOnInit hook most often, this is where we place any initialisation logic for our component. It’s preferred over initialising via the constructor since in the constructor we don’t yet have access to the input properties whereas by the time ngOnInit is called they have been bound to and are available to use.

{color:#191918;}ngOnChanges is the second most common hook, this is where we can find out details about which input properties have changed and how they have changed.

The third most common hook is
bc. {color:#191918;}ngOnDestroy which is where we place any cleanup logic for our component.

Listing

http://plnkr.co/edit/gIQCdWyb4sL4ZpDIyrFV?p=preview

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {
    Component,
    NgModule,
    Input,
    Output,
    EventEmitter,
    ViewEncapsulation,
    SimpleChanges,
    OnChanges,
    OnInit,
    DoCheck,
    AfterContentInit,
    AfterContentChecked,
    AfterViewInit,
    AfterViewChecked,
    OnDestroy
} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

class Joke { public setup: string; public punchline: string; public hide: boolean;

constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }

Component({ selector: 'joke', template: ` <div class="card card-block"> <h4 class="card-title"> <ng-content select=".setup"></ng-content> </h4> <p class="card-text" [hidden]="data.hide"> <ng-content select=".punchline"></ng-content> </p> <a class="btn btn-primary" (click)="data.toggle()">Tell Me </a> </div> ` }) class JokeComponent implements OnChanges, OnInit, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked, OnDestroy { Input(‘joke’) data: Joke;

constructor() { console.log(`new – data is ${this.data}`); } ngOnChanges(changes: SimpleChanges) { console.log(`ngOnChanges – data is ${this.data}`); for (let key in changes) { console.log(`${key} changed. Current: ${changes[key].currentValue}. Previous: ${changes[key].previousValue}`); } } ngOnInit() { console.log(`ngOnInit – data is ${this.data}`); } ngDoCheck() { console.log(“ngDoCheck”) } ngAfterContentInit() { console.log(“ngAfterContentInit”); } ngAfterContentChecked() { console.log(“ngAfterContentChecked”); } ngAfterViewInit() { console.log(“ngAfterViewInit”); } ngAfterViewChecked() { console.log(“ngAfterViewChecked”); } ngOnDestroy() { console.log(“ngOnDestroy”); } }

@Component({ selector: ‘joke-list’, template: `
{{ j.setup }}?

{{ j.punchline }}



`
})
class JokeListComponent { jokes: Joke[] = [];

addJoke() { this.jokes.unshift(new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”)); } deleteJoke() { this.jokes = [] } }

@Component({ selector: ‘app’, template: `

`
})
class AppComponent {
}

@NgModule({ imports: [BrowserModule], declarations: [ AppComponent, JokeComponent, JokeListComponent ], bootstrap: [AppComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

VIEWCHILDREN & CONTENTCHILDREN

Learning Objectives

{color:#191918;}

  • {color:#191918;}
    Understand the difference between view children and content children of a component.
  • {color:#191918;}
    Know how to get references to child components in host components.

Example application

The view children of a given component are the elements used within its template, its view.

We can get a reference to these view children in our component class by using the
bc. {color:#191918;}@ViewChild decorator.

We’ll explain how all this works using the joke application we’ve been working with so far in this course.

We’ve changed the application so that the
bc. {color:#191918;}JokeListComponent shows two jokes in it’s own view and one joke which is content projected from it’s host
bc. {color:#191918;}AppComponent, like so:

Listing 1. JokeListComponent

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-list',
  template: `
<h4>View Jokes</h4>
<joke *ngFor="let j of jokes" [joke]="j"> [_{color:#468C54;}①_]
  <span class="setup">{{ j.setup }}?</span>
  <h1 class="punchline">{{ j.punchline }}</h1>
</joke>

Content Jokes



`
})
class JokeListComponent { jokes: Joke[] = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”) ];
}pre

{color:#191918;}

  1. {color:#191918;} The component renders jokes in it’s own view.
  1. {color:#191918;} It also projects some content from it’s host component, in our example the other content is going to be a third joke.

Listing 2. AppComponent

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'app',
  template: `
<joke-list>
  <joke [joke]="joke"> [_{color:#468C54;}①_]
    <span class="setup">{{ joke.setup }}?</span>
    <h1 class="punchline">{{ joke.punchline }}</h1>
  </joke>
</joke-list>
`
})
class AppComponent {
  joke: Joke = new Joke("A kid threw a lump of cheddar at me", "I thought ‘That’s not very mature’");
}pre

{color:#191918;}

  1. {color:#191918;} Use content projection to inject a third joke into the
    bc. {color:#191918;}JokeListComponent.

When we view this app now we see 3 jokes, two of which are from the JokeListComponent and the third is projected in from the AppComponent.

ViewChild

In our
bc. {color:#191918;}JokeListComponent lets add a reference to the child
bc. {color:#191918;}JokeComponents that exists in it’s view.

We do this by using the
bc. {color:#191918;}@ViewChild decorator like so:

{color:#191918;}
bc. {color:#191918;}import { ViewChild } from '@angular/core';
.
.
.
@Component({
  selector: 'joke-list',
  template: `
<h4 #header>View Jokes</h4>
<joke *ngFor="let j of jokes" [joke]="j">
  <span class="setup">{{ j.setup }}?</span>
  <h1 class="punchline">{{ j.punchline }}</h1>
</joke>
<h4>Content Jokes</h4>
<ng-content></ng-content>
`
})
class JokeListComponent {
jokes: Joke[] = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”) ]; @ViewChild(JokeComponent) jokeViewChild: JokeComponent; constructor() { console.log(`new – jokeViewChild is ${this.jokeViewChild}`); } }pre

{color:#191918;}

  1. {color:#191918;} We are storing a reference to the child
    bc. {color:#191918;}JokeComponent in a property called
    bc. {color:#191918;}jokeViewChild.

{background:none;}

{color:#191918;}jokeViewChild isn’t an instance of a
bc. {color:#191918;}Joke class, it is the actual instance of the child
bc. {color:#191918;}JokeComponent that exists inside [_this_] components view.

We create a new property called
bc. {color:#191918;}jokeViewChild and we pre-pend this with a decorator of
bc. {color:#191918;}@ViewChild. This decorator tells Angular how to find the child component that we want to bind to this property.

A
bc. {color:#191918;}@ViewChild decorator means, search inside this components template, it’s view, for this child component.

The parameter we pass as the first argument to
bc. {color:#191918;}@ViewChild is the type of the component we want to search for, if it finds more than one it will just give us the first one it finds.

If we try to print out the reference in the constructor, like the code sample above,
bc. {color:#191918;}undefined will be printed out.

That’s because by the time the constructor is called we haven’t rendered the children yet. We render in a tree down approach so when a parent component is getting constructed it means the children are not yet created.

We can however hook into the lifecycle of the component at the point the view children have been created and that’s with the
bc. {color:#191918;}ngAfterViewInit hook.

To use this we need to make our component implement the interface
bc. {color:#191918;}AfterViewInit.

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-list',
  template: `
<h4 #header>View Jokes</h4>
<joke *ngFor="let j of jokes" [joke]="j">
  <span class="setup">{{ j.setup }}?</span>
  <h1 class="punchline">{{ j.punchline }}</h1>
</joke>
<h4>Content Jokes</h4>
<ng-content></ng-content>
`
})
class JokeListComponent implements AfterViewInit {
jokes: Joke[] = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”) ]; @ViewChild(JokeComponent) jokeViewChild: JokeComponent; constructor() { console.log(`new – jokeViewChild is ${this.jokeViewChild}`); } ngAfterViewInit() { console.log(`ngAfterViewInit – jokeViewChild is ${this.jokeViewChild}`); } }pre

In the
bc. {color:#191918;}ngAfterViewInit function
bc. {color:#191918;}jokeViewChild has been initialised and we can see it logged in the console.

ViewChildren

The above isn’t so useful in our case since we have multiple joke children components. We can solve that by using the alternative
bc. {color:#191918;}@ViewChildren decorator along side the
bc. {color:#191918;}QueryList generic type.

{color:#191918;}
bc. {color:#191918;}import { ViewChildren, QueryList } from '@angular/core';
.
.
.
class JokeListComponent implements AfterViewInit {
jokes: Joke[] = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”) ]; ViewChild(JokeComponent) jokeViewChild: JokeComponent; ViewChildren(JokeComponent) jokeViewChildren: QueryList; ngAfterViewInit() { console.log(`ngAfterViewInit – jokeViewChild is ${this.jokeViewChild}`); let jokes: JokeComponent[] = this.jokeViewChildren.toArray(); console.log(jokes); } }pre

{color:#191918;}

  1. {color:#191918;} We use the
    bc. {color:#191918;}@ViewChildren decorator which matches all
    bc. {color:#191918;}JokeComponent`s and stores them in a `QueryList called jokeViewChildren.
  1. {color:#191918;} We can convert our
    bc. {color:#191918;}QueryList of
    bc. {color:#191918;}JokeComponent`s into an array by calling `toArray()

When we run the above application we see two
bc. {color:#191918;}JokeComponents printed to the console, like so:

{color:#191918;}
bc. {color:#191918;}Array[2]
> 0: JokeComponent
> 1: JokeComponentpre

{background:none;}

The reason we see 2 jokes printed out and 3 is because only two of the jokes are view children the other joke is a content child. We cover content children in the end of ths lecture.

ViewChild referencing a template local variable

One practical application of
bc. {color:#191918;}@ViewChild is to get access to template local variables in our component class.

In the past we’ve said that template local variables are just that, local to the template.

But as the first param to the
bc. {color:#191918;}@ViewChild decorator we can also pass the name of a template local variable and have Angular store a reference to that variable on our component, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'joke-list',
  template: `
<h4 #header>View Jokes</h4>
<joke *ngFor="let j of jokes" [joke]="j">
  <span class="setup">{{ j.setup }}?</span>
  <h1 class="punchline">{{ j.punchline }}</h1>
</joke>
<h4>Content Jokes</h4>
<ng-content></ng-content>
`
})
class JokeListComponent implements AfterViewInit {
jokes: Joke[] = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”) ]; ViewChild(JokeComponent) jokeViewChild: JokeComponent; ViewChildren(JokeComponent) jokeViewChildren: QueryList; @ViewChild(“header”) headerEl: ElementRef; ngAfterViewInit() { console.log(`ngAfterViewInit – jokeViewChild is ${this.jokeViewChild}`); let jokes: JokeComponent[] = this.jokeViewChildren.toArray(); console.log(jokes); console.log(`ngAfterViewInit – headerEl is ${this.headerEl}`); //noinspection TypeScriptUnresolvedVariable this.headerEl.nativeElement.textContent = “Best Joke Machine”; } }pre

{color:#191918;}

  1. {color:#191918;} The type of our template variable is an
    bc. {color:#191918;}ElementRef, which is a low level reference to any element in the DOM. We are requesting a reference to the header template variable which points to the first
    bc. {color:#191918;}

     element in the template.

  1. {color:#191918;} Since
    bc. {color:#191918;}headerEl is an
    bc. {color:#191918;}ElementRef we can interact with the DOM directly and change the title of our header to Best Joke Machine.

{background:none;}

It’s not recommended to interact with the DOM directly with an
bc. {color:#191918;}ElementRef since that results in code that’s not very portable.

ContentChild & ContentChildren

The concept of a content child is similar to that of a view child but the content children of the given component are the child elements that are projected into the component from the host component.

In our example application we are projecting one joke in from the host
bc. {color:#191918;}AppComponent.

To get a reference to that child we can use either the
bc. {color:#191918;}@ContentChild or the
bc. {color:#191918;}@ContentChildren decorators. They work in similar ways to the view child counterparts,
bc. {color:#191918;}@ContentChild returns one child and
bc. {color:#191918;}@ContentChildren returns a
bc. {color:#191918;}QueryList.

Lets use
bc. {color:#191918;}@ContentChild to get a reference to the third joke that is projected in, like so:

{color:#191918;}
bc. {color:#191918;}import { ContentChildren, ContentChild } from '@angular/core';
.
.
.
class JokeListComponent implements AfterContentInit, AfterViewInit { [_{color:#468C54;}①_]
jokes: Joke[] = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”) ]; ViewChild(JokeComponent) jokeViewChild: JokeComponent; ViewChildren(JokeComponent) jokeViewChildren: QueryList; @ViewChild(“header”) headerEl: ElementRef; @ContentChild(JokeComponent) jokeContentChild: JokeComponent; ngAfterContentInit() { console.log(`ngAfterContentInit – jokeContentChild is ${this.jokeContentChild}`); } ngAfterViewInit() { console.log(`ngAfterViewInit – jokeViewChild is ${this.jokeViewChild}`); let jokes: JokeComponent[] = this.jokeViewChildren.toArray(); console.log(jokes); console.log(`ngAfterViewInit – headerEl is ${this.headerEl}`); this.headerEl.nativeElement.textContent = “Best Joke Machine”; } }pre

{color:#191918;}

  1. {color:#191918;} Just like before we need to tap into one of the component lifecycle hooks, this time it’s
    bc. {color:#191918;}AfterContentInit
  1. {color:#191918;} We create a
    bc. {color:#191918;}jokeContentChild property and bind it to the content child by using the
    bc. {color:#191918;}@ContentChild decorator.
  1. {color:#191918;} By the time the
    bc. {color:#191918;}ngAfterContentInit hook is run the
    bc. {color:#191918;}jokeContentChild property is set to the content child.

{background:none;}

You can implement multiple interfaces just by separating them with a
bc. {color:#191918;},.

If we logged
bc. {color:#191918;}jokeContentChild in our constructor it would again log undefined, since it’s not actually initialised at that point.

Content children are only visible by the time the
bc. {color:#191918;}AfterContentInit lifecycle hook has run.

Summary

An Angular application is composed from a number of components nested together.

These components can nest in two ways, as view children, in the template for that component. Or they can nest as content children, via content projection from a host component.

As developers of our components we can get access to these child components via the
bc. {color:#191918;}@ViewChild and
bc. {color:#191918;}@ContentChild (and
bc. {color:#191918;}@ViewChildren and
bc. {color:#191918;}@ContentChildren) decorators.

View children of a component are the components and elements in this components view.

Content children of a component are the components and elements that are projected into this components view by a host component.

View children are only initialised by the time the
bc. {color:#191918;}AfterViewInit lifecycle phase has been run.

Content children are only initialised by the time the
bc. {color:#191918;}AfterContentInit lifecycle phase has been run.

Listing

http://plnkr.co/edit/V6tqGnvNiiOOMMLmajKP?p=preview

Listing 3. script.ts

{color:#191918;}
bc. {color:#191918;}import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {
    Component,
    NgModule,
    Input,
    Output,
    EventEmitter,
    ViewEncapsulation,
    SimpleChanges,
    OnChanges,
    OnInit,
    DoCheck,
    AfterContentInit,
    AfterContentChecked,
    AfterViewInit,
    AfterViewChecked,
    OnDestroy,
    ViewChild,
    ViewChildren,
    ContentChild,
    ContentChildren,
    ElementRef,
    QueryList
} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';

class Joke { public setup: string; public punchline: string; public hide: boolean;

constructor(setup: string, punchline: string) { this.setup = setup; this.punchline = punchline; this.hide = true; } toggle() { this.hide = !this.hide; } }

@Component({ selector: ‘joke’, template: `


`
})
class JokeComponent {

@Input(‘joke’) data: Joke; }

@Component({ selector: ‘joke-list’, template: `

View Jokes


{{ j.setup }}?

{{ j.punchline }}



Content Jokes



`
})
class JokeListComponent implements OnInit, AfterContentInit, AfterViewInit {

jokes: Joke[] = [ new Joke(“What did the cheese say when it looked in the mirror”, “Hello-me (Halloumi)”), new Joke(“What kind of cheese do you use to disguise a small horse”, “Mask-a-pony (Mascarpone)”) ]; ViewChild(JokeComponent) jokeViewChild: JokeComponent; ViewChildren(JokeComponent) jokeViewChildren: QueryList; ViewChild("header") headerEl: ElementRef; ContentChild(JokeComponent) jokeContentChild: JokeComponent; constructor() { console.log(`new – jokeViewChild is ${this.jokeViewChild}`); console.log(`new – jokeContentChild is ${this.jokeContentChild}`); } ngAfterContentInit() { console.log(`ngAfterContentInit – jokeContentChild is ${this.jokeContentChild}`); } ngAfterViewInit() { console.log(`ngAfterViewInit – jokeViewChild is ${this.jokeViewChild}`); let jokes: JokeComponent[] = this.jokeViewChildren.toArray(); console.log(jokes); console.log(`ngAfterViewInit – headerEl is ${this.headerEl}`); this.headerEl.nativeElement.textContent = “Best Joke Machine”; } }

@Component({ selector: ‘app’, template: `
{{ joke.setup }}?

{{ joke.punchline }}



`
})
class AppComponent { joke: Joke = new Joke(“A kid threw a lump of cheddar at me”, “I thought ‘That’s not very mature’”);
}

@NgModule({ imports: [BrowserModule], declarations: [ AppComponent, JokeComponent, JokeListComponent ], bootstrap: [AppComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);pre

WRAPPING UP

In this section we covered Components in much more detail than the quickstart.

We discussed how to architect your application using components in Angular. We explained one method of breaking down your applications design into components with clear responsibilities, inputs and outputs.

We covered some of of the ways we can configure a component via the
bc. {color:#191918;}@Component decorator, specifically the
bc. {color:#191918;}templateUrl,
bc. {color:#191918;}styles,
bc. {color:#191918;}styleUrls and
bc. {color:#191918;}encapsulation configuration properties.

We covered the mechanism of content projection in Angular with the
bc. {color:#191918;}ng-content tag.

We explained the various component lifecycle phases, when they are run and how to hook into them with functions on the component.

Finally we covered the idea of view and content children and how to get references to each in a component.

ACTIVITY

Create a set of components with work together to create a Carousel which we can use to display different images in rotation.

We also want the carousel delay between rotations to be configurable.

The markup for our carousel will look like so:

{color:#191918;}
bc. {color:#191918;}<carousel [delay]="2000">
  <carousel-item>
    <img src="https://unsplash.it/200?image=0" alt="">
  </carousel-item>
  <carousel-item>
    <img src="https://unsplash.it/200?image=100" alt="">
  </carousel-item>
  <carousel-item>
    <img src="https://unsplash.it/200?image=200" alt="">
  </carousel-item>
</carousel>pre

Steps

Fork this plunker:

http://plnkr.co/edit/oajylErBv8adMGXywNTC?p=preview

Finish off the components to implement the carousel.

Read any TODO comments in the plunker for hints.

Solution

When you are ready compare your answer to the solution in this plunker:

http://plnkr.co/edit/0qNIQ7AyXuFafusV6XPX?p=preview

OVERVIEW

We’ve covered Components in the last section, in this section and the next we’ll cover the concept of Directives.

We’ve touched on a few directives already, such as
bc. {color:#191918;}NgFor.

Directives are components without a view. They are components without a template. Or to put it another way, components are directives with a view.

Everything you can do with a directive you can also do with a component. But not everything you can do with a component you can do with a directive.

We typically associate directives to existing elements by use attribute selectors, like so:

{color:#191918;}
bc. {color:#191918;}<elemenent aDirective></element>pre

{background:none;}

We capitalise the name of directives when we are talking about the directive class. For example when we say
bc. {color:#191918;}NgFor we mean the class which defines the
bc. {color:#191918;}NgFor directive.

When we are talking about either an instance of a directive or the attribute we use to associate a directive to an element we lowercase the first letter. So
bc. {color:#191918;}ngFor refers to both the instance of a directive and the _attribut_e name used to associate a directive with an element.

In this section we are going to cover the built in directives that come bundled with Angular.

NGFOR

Learning Objectives

{color:#191918;}

  • {color:#191918;}
    Know how to use the
    bc. {color:#191918;}NgFor directive in your application.
  • {color:#191918;}
    Know how to get the index in the array of the item you are looping over.
  • {color:#191918;}
    Know how to nest multiple
    bc. {color:#191918;}NgFor directives together.

Basics

We’ve covered this directive before in the quickstart.

{color:#191918;}NgFor is a structural directive, meaning that it changes the structure of the DOM.

It’s point is to repeat a given HTML template once for each value in an array, each time passing it the array value as context for string interpolation or binding.

{background:none;}

This directive is the successor of Angular 1s
bc. {color:#191918;}ng-repeat directive.

Let’s take a look at an example:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'ngfor-example',
  template: `
 <ul>
  <li *ngFor="let person of people"> [_{color:#468C54;}①_]
    {{ person.name }}
  </li>
 </ul>
 `
})
class NgForExampleComponent {
  people: any[] = [
    {
      "name": "Douglas  Pace"
    },
    {
      "name": "Mcleod  Mueller"
    },
    {
      "name": "Day  Meyers"
    },
    {
      "name": "Aguirre  Ellis"
    },
    {
      "name": "Cook  Tyson"
    }
  ];
}pre

{color:#191918;}

  1. {color:#191918;} We loop over each
    bc. {color:#191918;}person in the
    bc. {color:#191918;}people array and print out the persons name.

The syntax is
bc. {color:#191918;}*ngFor=“let of “.

 is a variable name of your choosing,  is a property on your component which holds a collection, usually an array but anything that can be iterated over in a
bc. {color:#191918;}for-of loop.

If we ran the above we would see this:

Index

Sometimes we also want to get the index of the item in the array we are iterating over.

We can do this by adding another variable to our
bc. {color:#191918;}ngFor expression and making it equal to
bc. {color:#191918;}index, like so:

{color:#191918;}
bc. {color:#191918;}<ul> [_{color:#468C54;}①_]
  <li *ngFor="let person of people; let i = index"> [_{color:#468C54;}①_]
    {{ i + 1 }} - {{ person.name }} [_{color:#468C54;}②_]
  </li>
</ul>pre

{color:#191918;}

  1. {color:#191918;} We create another variable called
    bc. {color:#191918;}i and make it equal to the special keyword
    bc. {color:#191918;}index.
  1. {color:#191918;} We can use the variable
    bc. {color:#191918;}i just like we can use the variable
    bc. {color:#191918;}person in our template.

If we ran the above we would now see this:

{background:none;}

The index is always zero based, so starts at 0 then 1,2,3,4 etc..

{background:none;}

In Angular 1 the variable
bc. {color:#191918;}$index would automatically be available for us to use in an
bc. {color:#191918;}ng-repeat directive. In Angular 2 we now need to provide this variable explicitly.

Grouping

If our data structure was in fact grouped by country we can use two
bc. {color:#191918;}ngFor directives, like so:

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'ngfor-grouped-example',
  template: `
 <h4>NgFor (grouped)</h4>
 <ul *ngFor="let group of peopleByCountry"> [_{color:#468C54;}①_]
   <li>{{ group.country }}</li>
   <ul>
    <li *ngFor="let person of group.people"> [_{color:#468C54;}②_]
      {{ person.name }}
    </li>
   </ul>
 </ul>
 `
})
class NgForGroupedExampleComponent {
peopleByCountry: any[] = [ { ‘country’: ‘UK’, ‘people’: [ { “name”: “Douglas Pace” }, { “name”: “Mcleod Mueller” }, ] }, { ‘country’: ‘US’, ‘people’: [ { “name”: “Day Meyers” }, { “name”: “Aguirre Ellis” }, { “name”: “Cook Tyson” } ] } ]; }pre

{color:#191918;}

  1. {color:#191918;} The first
    bc. {color:#191918;}ngFor loops over the groups, each grop contains a
    bc. {color:#191918;}country property which we render out on the next line and a
    bc. {color:#191918;}people array property.
  1. {color:#191918;} To loop over the
    bc. {color:#191918;}people array we create a second nested
    bc. {color:#191918;}ngFor directive.

If we ran the above we would see:

Summary

We use the
bc. {color:#191918;}NgFor directive to loop over an array of items and create multiple elements dynamically from a template element.

The template element is the element the directive is attached to.

We can nest muliple
bc. {color:#191918;}NgFor directives together.

We can get the index of the item we are looping over by assigning
bc. {color:#191918;}index to a variable in the
bc. {color:#191918;}NgFor expression.

Listing

http://plnkr.co/edit/n76eLP4d1SubfA2u9FeD?p=preview

Listing 2. script.ts

{color:#191918;}
bc. {color:#191918;}import {NgModule, Component} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

@Component({ selector: ‘ngfor-example’, template: `

NgFor


  • {{ i + 1 }} – {{ person.name }}

`
})
class NgForExampleComponent { people: any[] = [ { “name”: “Douglas Pace” }, { “name”: “Mcleod Mueller” }, { “name”: “Day Meyers” }, { “name”: “Aguirre Ellis” }, { “name”: “Cook Tyson” } ];
}

@Component({ selector: ‘ngfor-grouped-example’, template: `

NgFor (grouped)


  • {{ group.country }}
    • {{ person.name }}

`
})
class NgForGroupedExampleComponent {

peopleByCountry: any[] = [ { ‘country’: ‘UK’, ‘people’: [ { “name”: “Douglas Pace” }, { “name”: “Mcleod Mueller” }, ] }, { ‘country’: ‘US’, ‘people’: [ { “name”: “Day Meyers” }, { “name”: “Aguirre Ellis” }, { “name”: “Cook Tyson” } ] } ]; }

@Component({ selector: ‘directives-app’, template: ` `
})
class DirectivesAppComponent {
}

@NgModule({ imports: [BrowserModule], declarations: [ NgForExampleComponent, NgForGroupedExampleComponent, DirectivesAppComponent], bootstrap: [DirectivesAppComponent],
})
class AppModule {

}

platformBrowserDynamic().bootstrapModule(AppModule);
pre

NGIF & NGSWITCH

Learning Objectives

{color:#191918;}

  • {color:#191918;}
    Know how to conditionally add or remove an element from the DOM using the
    bc. {color:#191918;}NgIf directive.
  • {color:#191918;}
    Know how to conditionally add or remove elements from the DOM using the
    bc. {color:#191918;}NgSwitch directive.

NgIf

The
bc. {color:#191918;}NgIf directive is used when you want to display or remove an element based on a condition.

If the condition is
bc. {color:#191918;}false the element the directive is attached to will be removed from the DOM.

{background:none;}

The difference between
bc. {color:#191918;}[hidden]=‘false‘ and
bc. {color:#191918;}*ngIf=‘false‘ is that the first method simply hides the element. The second method with
bc. {color:#191918;}ngIf removes the element completely from the DOM.

We define the condition by passing an expression to the directive which is evaluated in the context of it’s host component.

The syntax is:
bc. {color:#191918;}*ngIf=”“

Lets use this in an example, we’ve taken the same code sample as we used for the
bc. {color:#191918;}NgFor lecture but changed it slightly. Each person now has an age as well as a name.

Lets add an
bc. {color:#191918;}NgIf directive to the template so we only show the element if the age is less than 30, like so:

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'ngif-example',
  template: `
<h4>NgIf</h4>
<ul *ngFor="let person of people">
  <li *ngIf="person.age < 30"> [_{color:#468C54;}①_]
  {{ person.name }} ({{ person.age }})
  </li>
</ul>
`
})
class NgIfExampleComponent {
people: any[] = [ { “name”: “Douglas Pace”, “age”: 35 }, { “name”: “Mcleod Mueller”, “age”: 32 }, { “name”: “Day Meyers”, “age”: 21 }, { “name”: “Aguirre Ellis”, “age”: 34 }, { “name”: “Cook Tyson”, “age”: 32 } ]; }pre

{color:#191918;}

  1. {color:#191918;} The
    bc. {color:#191918;}NgIf directive removes the
    bc. {color:#191918;}li element from the DOM if
    bc. {color:#191918;}person.age is less than 30.

If we ran the above we would see:

{background:none;}

We can’t have two structural directives, directives starting with a *, attached to the same element.

The below code would not work:

{color:#191918;}
bc. {color:#191918;}<ul *ngFor="let person of people" *ngIf="person.age < 30">
  <li>{{ person.name }}</li>
</ul>pre

{background:none;}

This is exactly the same as Angular 1’s
bc. {color:#191918;}ng-if directive however Angular 2 doesn’t have a built-in alternative for
bc. {color:#191918;}ng-show. To achieve something similar you can bind to the
bc. {color:#191918;}[hidden] property or use the
bc. {color:#191918;}NgStyle or
bc. {color:#191918;}NgClass directives we cover later in this section.

NgSwitch

Lets imagine we wanted to print peoples names in different colours depending on where they are from. Green for UK, Blue for USA, Red for HK.

With bootstrap we can change the text color by using the
bc. {color:#191918;}text-danger,
bc. {color:#191918;}text-success,
bc. {color:#191918;}text-warning and
bc. {color:#191918;}text-primary classes.

We could solve this by having a series of *ngIf statements, like so:

{color:#191918;}
bc. {color:#191918;}<ul *ngFor="let person of people">
  <li *ngIf="person.country ==='UK'"
      class="text-success">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngIf="person.country === 'USA'"
      class="text-primary">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngIf="person.country === 'HK'"
      class="text-danger">{{ person.name }} ({{ person.country }})
  </li>
  <li *ngIf="person.country !== 'HK' && person.country !== 'UK' && person.country !== 'USA'"
      class="text-warning">{{ person.name }} ({{ person.country }})
  </li>
</ul>pre

This initially seems to make sense until we try to create our else style element. We have to check to see if the person is not from any of the countries we have specified before. Resulting in a pretty long
bc. {color:#191918;}ngIf expression and it will only get worse the more countries we add.

Most languages, including javascript, have a language construct called a
bc. {color:#191918;}switch statement to solve this kind of problem. Angular also provides us with similar functionality via something called the
bc. {color:#191918;}NgSwitch directive.

This directive allows us to render different elements depending on a given condition, in fact the
bc. {color:#191918;}NgSwitch directive is actually a number of directives working in conjunction, like so:

Listing 1. script.ts

{color:#191918;}
bc. {color:#191918;}@Component({
  selector: 'ngswitch-example',
  template: `<h4>NgSwitch</h4>
<ul *ngFor="let person of people"
    [ngSwitch]="person.country"> [_{color:#468C54;}①_]
  • ② class="text-success">{{ person.name }} ({{ person.country }})
  • {{ person.name }} ({{ person.country }})
  • {{ person.name }} ({{ person.country }})
  • ③ class="text-warning">{{ person.name }} ({{ person.country }})
  • ` }) class NgSwitchExampleComponent { people: any[] = [ { “name”: “Douglas Pace”, “age”: 35, “country”: ‘MARS’ }, { “name”: “Mcleod Mueller”, “age”: 32, “country”: ‘USA’ }, { “name”: “Day Meyers”, “age”: 21, “country”: ‘HK’ }, { “name”: “Aguirre Ellis”, “age”: 34, “country”: ‘UK’ }, { “name”: “Cook Tyson”, “age”: 32, “country”: ‘USA’ } ]; }pre

    {color:#191918;}

    1. {color:#191918;}
      We bind an expression to the
      bc. {color:#191918;}ngSwitch directive.
    1. {color:#191918;}
      The
      bc. {color:#191918;}ngSwitchCase directive lets us define a condition which if it matches the expression in (1) will render the element it’s attached to.
    1. {color:#191918;}
      If no conditions are met in the switch statement it will check to see if there is an ngSwitchDefault directive, if there is it will render the element thats attached to, however it is optional – if it’s not present it simply won’t display anything if no matching ngSwitchCase directive is found.

    The key difference between the
    bc. {color:#191918;}ngIf solution is that by using
    bc. {color:#191918;}NgSwitch we evaluate the expression only once and then choose the element to display based on the result.

    If we ran the above we would see:

    {background:none;}

    The use of
    bc. {color:#191918;}NgSwitch here is just for example and isn’t an efficient way of solving this problem. We would use either the
    bc. {color:#191918;}NgStyle or
    bc. {color:#191918;}NgClass directives which we’ll cover in the next lecture.

    Summary

    With
    bc. {color:#191918;}NgIf we can conditionally add or remove an element from the DOM.

    If we are faced with multiple conditions a cleaner alternative to multiple nested
    bc. {color:#191918;}NgIf statements is the
    bc. {color:#191918;}NgSwitch series of directives.

    Listing

    http://plnkr.co/edit/1mDlqE56ZxdiZbusUrva?p=preview

    Listing 2. script.ts

    {color:#191918;}
    bc. {color:#191918;}import {NgModule, Component} from '@angular/core';
    import {BrowserModule} from '@angular/platform-browser';
    import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

    @Component({ selector: ‘ngif-example’, template: `

    NgIf


    • {{ person.name }} ({{ person.age }})


    `
    })
    class NgIfExampleComponent {

    people: any[] = [ { “name”: “Douglas Pace”, “age”: 35 }, { “name”: “Mcleod Mueller”, “age”: 32 }, { “name”: “Day Meyers”, “age”: 21 }, { “name”: “Aguirre Ellis”, “age”: 34 }, { “name”: “Cook Tyson”, “age”: 32 } ]; }

    @Component({ selector: ‘ngswitch-example’, template: `

    NgSwitch


    • {{ person.name }} ({{ person.country }})
    • {{ person.name }} ({{ person.country }})
    • {{ person.name }} ({{ person.country }})
    • {{ person.name }} ({{ person.country }})
    ` }) class NgSwitchExampleComponent { people: any[] = [ { “name”: “Douglas Pace”, “age”: 35, “country”: ‘MARS’ }, { “name”: “Mcleod Mueller”, “age”: 32, “country”: ‘USA’ }, { “name”: “Day Meyers”, “age”: 21, “country”: ‘HK’ }, { “name”: “Aguirre Ellis”, “age”: 34, “country”: ‘UK’ }, { “name”: “Cook Tyson”, “age”: 32, “country”: ‘USA’ } ]; }

    @Component({ selector: ‘directives-app’, template: ` `
    })
    class DirectivesAppComponent {
    }

    @NgModule({ imports: [BrowserModule], declarations: [ NgIfExampleComponent, NgSwitchExampleComponent, DirectivesAppComponent], bootstrap: [DirectivesAppComponent]
    })
    class AppModule {

    }

    platformBrowserDynamic().bootstrapModule(AppModule);pre

    NGSTYLE & NGCLASS

    Learning Objectives

    {color:#191918;}

    • {color:#191918;}
      Understand when and how to use the
      bc. {color:#191918;}NgStyle directive to set an elements style.
    • {color:#191918;}
      Understand when and how to use the
      bc. {color:#191918;}NgClass directive to set an elements classes.

    NgStyle

    The
    bc. {color:#191918;}NgStyle directive lets you set a given DOM elements style properties.

    One way to set styles is by using the
    bc. {color:#191918;}NgStyle directive and assigning it an object literal, like so:

    {color:#191918;}
    bc. {color:#191918;}<div [ngStyle]="{'background-color':'green'}"></<div>pre

    This sets the background color of the
    bc. {color:#191918;}div to green.

    {color:#191918;}ngStyle becomes much more useful when the value is [_dynamic_]. The [_values_] in the object literal that we assign to
    bc. {color:#191918;}ngStyle can be javascript expressions which are evaluated and the result of that expression is used as the value of the css property, like this:
    {color:#191918;}
    bc. {color:#191918;}<div [ngStyle]="{'background-color':person.country === 'UK' ? 'green' : 'red' }"></<div>pre

    The above code uses the ternary operator to set the background color to green if the persons country is the UK else red.

    But the expression doesn’t have to be inline, we can call a function on the component instead.

    To demonstrate this lets flesh out a full example. Similar to the ones we’ve created before lets loop through an array of people and print out there names in different colors depending on the country they are from.

    {color:#191918;}
    bc. {color:#191918;}@Component({
      selector: 'ngstyle-example',
      template: `<h4>NgStyle</h4>
    <ul *ngFor="let person of people">
      <li [ngStyle]="{'color':getColor(person.country)}"> {{ person.name }} ({{ person.country }}) [_{color:#468C54;}①_]
      </li>
    </ul>
     `
    })
    class NgStyleExampleComponent {
    getColor(country) { switch (country) { case ‘UK’: return ‘green’; case ‘USA’: return ‘blue’; case ‘HK’: return ‘red’; } } people: any[] = [ { “name”: “Douglas Pace”, “country”: ‘UK’ }, { “name”: “Mcleod Mueller”, “country”: ‘USA’ }, { “name”: “Day Meyers”, “country”: ‘HK’ }, { “name”: “Aguirre Ellis”, “country”: ‘UK’ }, { “name”: “Cook Tyson”, “country”: ‘USA’ } ]; }pre

    {color:#191918;}

    1. {color:#191918;} We set the color of the text according to the value that’s returned from the
      bc. {color:#191918;}getColor function.
    1. {color:#191918;} Our
      bc. {color:#191918;}getColor function returns different colors depending on the country passed in.

    If we ran the above code we would see:

    Alternative syntax

    As well as using the
    bc. {color:#191918;}nyStyle directive we can also set individual style properties using the
    bc. {color:#191918;}[style.] syntax, for example
    bc. {color:#191918;}[style.color]=“getColor(person.country)“

    {color:#191918;}
    bc. {color:#191918;}<ul *ngFor="let person of people">
      <li [style.color]="getColor(person.country)">{{ person.name }} ({{ person.country }})
      </li>
    </ul>pre

    Points and pixels

    Lets imagine we wanted to set the font size to 24, we could use:

    {color:#191918;}
    bc. {color:#191918;}[ngStyle]="{'font-size':24}"pre

    But this wouldn’t work, it isn’t valid CSS to just set the font size to 24. We also have to specify a unit such as px or em.

    Angular comes to the rescue with a special syntax,
    bc. {color:#191918;}.. So for the above if we wanted the size to be 24 pixels we would write
    bc. {color:#191918;}[ngStyle]=”{‘font-size.px’:24}“

    {background:none;}

    The property name is
    bc. {color:#191918;}font-size.px and not just
    bc. {color:#191918;}font-size

    The
    bc. {color:#191918;}.px suffix says that we are setting the font-size in pixels. You could
    bc. {color:#191918;}.em to express the font size in ems or even in percentage using
    bc. {color:#191918;}.%

    This is also applicable with the alternative syntax, e.g:-

    {color:#191918;}[style.font-size.[*px*]]="24"

    Let’s change our demo application to display the names in a font size of 24 pixels, like so:

    {color:#191918;}
    bc. {color:#191918;}<ul *ngFor="let person of people">
      <li [ngStyle]="{'font-size.px':24}"
          [style.color]="getColor(person.country)">{{ person.name }} ({{ person.country }})
      </li>
    </ul>pre

    Running the above would display:

    NgClass

    The
    bc. {color:#191918;}NgClass directive allows you to set the CSS class dynamically for a DOM element.

    {background:none;}

    The
    bc. {color:#191918;}NgClass directive will feel very similar to what
    bc. {color:#191918;}ngClass used to do in Angular 1.

    There are two ways to use this directive, the first is by passing an object literal to the directive, like so:

    {color:#191918;}
    bc. {color:#191918;}[ngClass]="{'text-success':true}"pre

    When using an object literal, the keys are the classes which are added to the element if the value of the key evaluates to true.

    So in the above example, since the value is
    bc. {color:#191918;}true this will set the class
    bc. {color:#191918;}text-success onto the element the directive is attached to.

    The value can also be an expression, so we can re-write the above to be.

    {color:#191918;}
    bc. {color:#191918;}[ngClass]="{'text-success':person.country === 'UK'}"pre

    Lets implement the colored names demo app using
    bc. {color:#191918;}ngClass instead of
    bc. {color:#191918;}ngStyle.

    {color:#191918;}
    bc. {color:#191918;}<h4>NgClass</h4>
    <ul *ngFor="let person of people">
      <li [ngClass]="{
        'text-success':person.country === 'UK',
        'text-primary':person.country === 'USA',
        'text-danger':person.country === 'HK'
      }">{{ person.name }} ({{ person.country }})
      </li>
    </ul>pre

    Since the object literal can contain many keys we can also set many class names.

    We can now color our text with different colors for each country with one statement.

    If we ran the above code we would see:

    Alternative syntax

    We can also set a class on an element by binding to the input property binding called
    bc. {color:#191918;}class, like so
    bc. {color:#191918;}[class]=”‘text-success’“

    {background:none;}

    The
    bc. {color:#191918;}‘text-success‘ is wrapped with single quotes so when it’s evaluated as javascript it doesn’t try to treat
    bc. {color:#191918;}text-success as a variable.

    {background:none;}

    The above syntax removes all the existing classes for that element and replaces them with just ‘text-success’.

    If we want to just add
    bc. {color:#191918;}text-success to the list of classes already set on the element we can use the extended syntax
    bc. {color:#191918;}[class.]=‘truthy expression‘

    So for instanace to add text-success to the list of classes for an element we can use:

    {color:#191918;}
    bc. {color:#191918;}[class.text-success]="true"pre

    Or just like before we can use an expression as the value, like so:

    {color:#191918;}
    bc. {color:#191918;}[class.card-success]="person.country === 'UK'"pre

    And we can actually specify multiple values at one time, like so:

    {color:#191918;}
    bc. {color:#191918;}<ul *ngFor="let person of people">
      <li [class.text-success]="person.country === 'UK'"
          [class.text-primary]="person.country === 'USA'"
          [class.text-danger]="person.country === 'HK'">{{ person.name }} ({{ person.country }})
      </li>
    </ul>pre

    Summary

    Both the
    bc. {color:#191918;}NgStyle and
    bc. {color:#191918;}NgClass directives can be used to conditionally set the look and feel of your application.

    {color:#191918;}NgStyle gives you fine grained control on individual properties. But if you want to make changes to multiple properties at once, creating a class which bundles those properties and adding the class with
    bc. {color:#191918;}NgClass makes more sense.

    {background:none;}

    The object literal syntax is better for when you want to set multiple classes or styles in one statement. The shortcut syntax,
    bc. {color:#191918;}[style|class.], is better for setting a single class or style.

    Listing

    http://plnkr.co/edit/dTBP2dC0PaARD9Z9u0IC?p=preview

    Listing 1. script.ts

    {color:#191918;}
    bc. {color:#191918;}import {NgModule, Component} from '@angular/core';
    import {BrowserModule} from '@angular/platform-browser';
    import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

    @Component({ selector: ‘ngstyle-example’, template: `

    NgStyle


    • {{ person.name }} ({{ person.country }})

    `
    })
    class NgStyleExampleComponent {

    getColor(country) { switch (country) { case ‘UK’: return ‘green’; case ‘USA’: return ‘blue’; case ‘HK’: return ‘red’; } } people: any[] = [ { “name”: “Douglas Pace”, “country”: ‘UK’ }, { “name”: “Mcleod Mueller”, “country”: ‘USA’ }, { “name”: “Day Meyers”, “country”: ‘HK’ }, { “name”: “Aguirre Ellis”, “country”: ‘UK’ }, { “name”: “Cook Tyson”, “country”: ‘USA’ } ]; }

    @Component({ selector: ‘ngclass-example’, template: `

    NgClass


    • {{ person.name }} ({{ person.country }})

    `
    })
    class NgClassExampleComponent {

    people: any[] = [ { “name”: “Douglas Pace”, “age”: 35, “country”: ‘UK’ }, { “name”: “Mcleod Mueller”, “age”: 32, “country”: ‘USA’ }, { “name”: “Day Meyers”, “age”: 21, “country”: ‘HK’ }, { “name”: “Aguirre Ellis”, “age”: 34, “country”: ‘UK’ }, { “name”: “Cook Tyson”, “age”: 32, “country”: ‘USA’ } ]; }

    @Component({ selector: ‘directives-app’, template: `

    `
    })
    class DirectivesAppComponent {
    }

    @NgModule({ imports: [BrowserModule], declarations: [ NgClassExampleComponent, NgStyleExampleComponent, DirectivesAppComponent], bootstrap: [DirectivesAppComponent]
    })
    class AppModule {

    }

    platformBrowserDynamic().bootstrapModule(AppModule);pre

    NGNONBINDABLE

    Learning Objectives

    {color:#191918;}

    • {color:#191918;}
      Understand when and how to use the
      bc. {color:#191918;}NgNonBindable directive.

    Description

    We use
    bc. {color:#191918;}ngNonBindable when we want tell Angular not to compile, or bind, a particular section of our page.

    The most common example of this is if we wanted to write out some Angular code on the page, for example if we wanted to render out the text
    bc. {color:#191918;}{{ name }} on our page, like so:

    {color:#191918;}
    bc. {color:#191918;}<div>
      To render the name variable we use this syntax <pre>{{ name }}</pre>
    </div>pre

    Normally Angular will try to find a variable called
    bc. {color:#191918;}name on the component and print out the value of the
    bc. {color:#191918;}name variable instead of just printing out
    bc. {color:#191918;}{{ name }}.

    To make angular ignore an element we simply add the
    bc. {color:#191918;}ngNonBindable directive to the element, like so:

    {color:#191918;}
    bc. {color:#191918;}<div>
      To render the name variable we use this syntax <pre ngNonBindable>{{ name }}</pre>
    </div>pre

    If we run this in the browser we would see:

    Summary

    We use
    bc. {color:#191918;}NgNonBindable when we want to tell Angular not to perform any binding for an element.

    Listing

    http://plnkr.co/edit/1u12vtOPFA9K00jvUjlO?p=preview

    Listing 1. script.ts

    {color:#191918;}
    bc. {color:#191918;}import {NgModule, Component} from '@angular/core';
    import {BrowserModule} from '@angular/platform-browser';
    import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';

    @Component({ selector: ‘ngnonbindable-example’, template: `

    NgNonBindable


    To render the name variable we use this syntax
    {{ name }}

    `
    })
    class NgNonBindableExampleComponent {
    }

    @Component({ selector: ‘directives-app’, template: ``
    })
    class DirectivesAppComponent {
    }

    @NgModule({ imports: [BrowserModule], declarations: [NgNonBindableExampleComponent, DirectivesAppComponent], bootstrap: [DirectivesAppComponent],
    })
    class AppModule {

    }

    platformBrowserDynamic().bootstrapModule(AppModule);
    pre

    STRUCTURAL DIRECTIVES

    Learning Objectives

    {color:#191918;}

    • {color:#191918;}
      Understand what a structural directive is.
    • {color:#191918;}
      Know why we use the
      bc. {color:#191918;}* character for some directives only.

    Long form structural directives

    Structural Directives are directives which change the structure of the DOM by adding or removing elements.

    There are three built in structural directives,
    bc. {color:#191918;}NgIf,
    bc. {color:#191918;}NgFor and
    bc. {color:#191918;}NgSwitch.

    These directives work by using the HTML5
    bc. {color:#191918;}