Angular 2 Weekend Light

Preview:

Citation preview

CoWork SouthBay 25 + 26 February 2017

Angular 2.0 Weekend Workshop

Troy Miles• Troy Miles aka the RocknCoder

• Over 38 years of programming experience

• Speaker and author

• bit.ly/rc-jquerybook

• rockncoder@gmail.com

• @therockncoder

• Now a lynda.com Author!

Build Mobile Apps!

• Develop mobile apps with Ionic and AngularJS

• Learn the Ionic CLI

• Fetch data via ajax

• Deploy your app to Android & iOS

• bit.ly/ionicvideo

April1&2

–Alejandro (Sicario 2015)

“Nothing will make sense to your American ears, and you will doubt everything that we do,

but in the end you will understand”

Agenda: Day One• Overview

• Angular CLI

• Webpack

• Modern JavaScript

• TypeScript

• Components / Views

• Router

• Data Binding

• Dependency Injection

• Services

Agenda: Day Two• HTTP

• Forms

• Pipes

• Directives

• RxJS

• Unit Testing

• Angular Material

• Summary

Tools• install git

• install node.js

• upgrade npm npm install npm -g

• install RxJS npm install -g rxjs

• install Angular CLI npm install -g @angular/cli

• install Firebase: npm install -g firebase-tools

Check Versionsapp command my version

git git —version 2.11.0

node.js node -v v7.4.0

npm npm —v 4.0.5

angular cli ng -v 1.0.0-beta.32.3

firebase firebase version 3.3.0

Application Root Directory

• All of the commands, for all of the tools are designed work on the application root directory

• If used anywhere else bad things will happen

• be sure you are in the app root

• double check that you are in the app root

Angular CLITool Command

New App ng new <app-name>

Web Server ng serve

Unit Test ng test

End to End Test ng e2e

Dev Build ng build dev

Production Build ng build prod

Create New ComponentsComponent CommandClass ng g class my-new-classComponent ng g component my-new-componentDirective ng g directive my-new-directiveEnum ng g enum my-new-enumInterface ng g interface my-new-interfaceModule ng g module my-modulePipe ng g pipe my-new-pipeService ng g service my-new-service

naming convention• Angular apps are usually built using lowercase

kebab naming convention

• words are lowercase, dash as separator

• final word is the thing’s type, a dot is its separator

• if the thing is a class, no final word

• contact-details.component.ts

Webpack

• Open source module bundler

• Replaces System.JS

• Works with JS, CSS, and HTML

• Minifies, Concatenates, and Bundles

Firebase commandsCommand What?

firebase login logins into your firebase account

firebase init sets up a new firebase project

firebase deploy deploys your app to firebase hosting

firebase list lists all your firebase projects

firebase open open project resources

firebase use —add adds the current

Firebase Steps1. Create project in Firebase

2. Go to application root in terminal/ cmd prompt

3. firebase login

4. firebase init (connects app to firebase project)

5. ng build prod (creates “dist" directory)

6. firebase deploy

7. Refresh cache (Chrome: cmd+shift+R / ctrl+shift+R )

ECMAScript VersionsVersion Date

ES1 June 1997

ES2 June 1998

ES3 December 1999

ES4 DOA 2006

ES5 December 2009

ES6/ES2015 June 2015

ES2016 2016

2009 • ES3 ruled the land, it is 10 years old

• ES4 was abandoned due to infighting

• ES5 was in development, strict mode still a dream

• FireFox 3.5 is the most popular browser

• AngularJS is born

AngularJS

• Created by Miško Hevery and Adam Abrons in 2009

• JavaScript MVC

• Declarative programming for UI

• Imperative programming for business logic

AngularJS Main Parts• Module

• Views/Controllers

• Services

• Directives

• Filters

Since 2009• Two new versions of JavaScript (ES5 & ES6)

• Lots of new browser capabilities

• Transpilers like TypeScript and Babel

• Cool libraries like RxJS and React

• No longer necessary for Angular to do everything

Getting started• npm install typescript -g

• git clone https://github.com/Rockncoder/quizzer-start.git

• cd quizzer-start

• npm install

• npm start

• refresh browser

npm

npm• We need Nodejs for its package manager, npm

• NPM requires a file, package.json, in the app root

• We use npm for a lot of things

• npm officially doesn’t stand for anything

• https://www.npmjs.com/

package.json• name - what this app is called, for npm it must be

• version - the current version number

• description - what this package is all about

• author - who wrote it

• repository - where it lives

package.json

• license - type of license granted to users of the package

• scripts - commands

• dependencies - packages for production

• devDependencies - packages for development

version definitions• “^1.8.9"

• 1 - is the major number

• 8 - is the minor number

• 9 - is the patch number

• patch number is not required

version symbols• "1.8.9" - must exactly match version

• ">1.8.9" - must be greater than version

• ">=1.8.9", "<1.8.9", "<=1.8.9"

• "^1.8.9"- allows changes to the minor & patch

• "~1.8.9" - allows changes to the patch

• "1.8.*" - a wild card which stands for any value here

install• The install adds a package to your app

• npm install <package name> [—save | —save-dev]

• npm i <package name> [-d | -D]

• —save: saves info to dependencies

• —save-dev: saves info to devDependencies

run-script

• npm run-script <command> <args>

• npm run <command> <args> (shortcut)

• to abort use control-c

What’s in our package.json?• angular2 - Needs no explanation

• es6-promise - A polyfill for ES6 promises

• es6-shim - A library that aligns JavaScript more closely to ES6

• reflect-metadata - Polyfill for ES7 decorators

• rxjs - a library for asynchronous and event based programming

• systemjs - a module loading system

• zone.js - for change detection

What’s in our package.json?

• concurrently - runs multiple commands concurrently

• lite-server - a light development node server

• typescript - a language for application scale JS

• typings - the typescript definition manager

Where can you look up npm info?

• https://angular.io/

• https://www.npmjs.com/

• https://angularjs.org/

• https://nodejs.org/

What’s difference between the ‘^’ and the ‘~’ in packages?

A. The ~ means any version greater than this one, while the ^ means any version less than this one

B. The ~ is a wild card but the ^ means only this version

C. The ~ allows different patch number, while the ^ allows changes to both minor and patch numbers

Angular 2

It’s not AngularJS 2• ES5

• ES6

• CoffeeScript

• Dart

• TypeScript

Deleted from Angular 2• $scope

• Data Definition Object

• angular module

• controllers

• jqLite / jQuery

Main Parts• Module

• Component

• Template

• Data binding

• Metadata

• Service

• Directive

• Dependency Injection

ES5

strict mode• 'use strict’; or "use strict;"

• First line of file or function

• Can break working code!!

• More stringent checking

• Enables ES5 features

strict mode• Variables must be declared

• Functions defined only at the top scope level

• “this” is undefined at the global level

• Throws error when you forget the 'new' keyword in constructor

• Can't use the same function parameter twice

Array Functions• .isArray()

• .every()

• .forEach()

• .indexOf()

• .lastIndexOf()

• .some()

• .map()

• .reduce()

• .filter()

forEachlet junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}]; let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']; let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; console.log(nums); // forEach iterates over the array, once for each element, but there is no way to // break outnums.forEach(function (elem, index, arr) { console.log(index + ': ' + elem); });

maplet junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}]; let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']; let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; console.log(nums); // map iterates over all of the elements and returns a new array with the same // number of elementslet nums2 = nums.map((elem) => elem * 2); console.log(nums2);

filterlet junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}]; let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']; let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; console.log(nums); // filter iterates over the array and returns a new array with only the elements // that pass the testlet nums3 = nums.filter((elem) => !!(elem % 2)); console.log(nums3);

reducelet junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}]; let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']; let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; console.log(nums); // reduce iterates over the array passing the previous value and the current// element it is up to you what the reduction does, let's concatenate the stringslet letters2 = letters.reduce((previous, current) => previous + current); console.log(letters2); // reduceRight does the same but goes from right to leftlet letters3 = letters.reduceRight((previous, current) => previous + current); console.log(letters3);

everylet junk = [1, 2, 3, 4, 'Alpha', 5, {name: 'Jason'}]; let letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K']; let nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; console.log(nums); // every makes sure that all the elements match the expressionlet isEveryNumbers = junk.every((elem) => typeof elem === 'number'); console.log('Are all members of junk numbers: ' + isEveryNumbers);

JSON Object• JSON strings must be double quote

• key/value pairs

• key is any valid JS string

• value is an valid JS data type

• .stringify() - converts object to JSON string

• .parse() - converts JSON string to object

JSON data{ "title": "U.S. Citizenship", "tagLine": "Think you can pass this quiz of basic knowledge of American government, history, and geography?", "added": "2015-07-04T18:25:43.511Z", "rating": 3, "_id": 1, "tags": [ "history", "geography", "United States" ] }

How do you turn a JS object into a JSON string?

A. JSON.parse()

B. Math.obj()

C. .toString()

D. JSON.stringify()

ES6 (ES2015)

ES2015 aka ES6• let

• const

• Template strings

• Arrow functions

• for-of

• Classes

• Promises

• Using ES6 today

let

• let allows us to create a block scoped variables

• they live and die within their curly braces

• best practice is to use let instead of var

let// let allows us to create block scoped variables// they live and die within the curly braceslet val = 2; console.info(`val = ${val}`); { let val = 59; console.info(`val = ${val}`); } console.info(`val = ${val}`);

const

• const creates a variable that can't be changed

• best practice is to make any variable that should not change a constant

• does not apply to object properties or array elements

constconst name = 'Troy'; console.info(`My name is ${name}`); // the line below triggers a type errorname = 'Miles';

Template strings

• Defined by using opening & closing back ticks

• Templates defined by ${JavaScript value}

• The value can be any simple JavaScript expression

• Allows multi-line strings (return is pass thru)

Template strings let state = 'California'; let city = 'Long Beach'; console.info(`This weekend's workshop is in ${city}, ${state}.`); // template strings can run simple expressions like addition let cup_coffee = 4.5; let cup_tea = 2.5; console.info(`coffee: $${cup_coffee} + tea: $${cup_tea} = $${cup_coffee + cup_tea}.`); // they can allow us to create multi-line strings console.info(`This is line #1.this is line #2.`);

Arrow (lambda) functionlet anon_func = function (num1, num2) { return num1 + num2; }; console.info(`Anonymous func: ${anon_func(1, 2)}`); let arrow_func = (num1, num2) => num1 + num2; console.info(`Arrow func: ${arrow_func(3, 4)}`);

In a loop what do the break and continue instructions do?

A. break cause the program to halt all execute and continue resumes execution

B. break goes immediately to the top of the loop and continue exits the loop

C. break exits the loop and continue goes immediately to the top of the loop

for-of• for of lets us iterate over an array

• .entries() gives us the index and the element

• with destructuring we can use as variables

• unlike forEach, continue and break work

• break stop the loop

• continue stops the current iteration

for (let elem of pirateArray) { console.info(elem); } // if we want the element and its index we can get it toofor (let [index, elem] of pirateArray.entries()) { if (index === 5) { break; } console.info(`${index}. ${elem}`); } // unlike forEach, continue and break workfor (let [index, elem] of pirateArray.entries()) { if (index === 5) { continue; } console.info(`${index}. ${elem}`); }

for-of

class// class must exist before usageclass Animal { constructor(name) { this.name = name; this.legs = 2; } showNameAndLegs() { console.info(`${this.name} has ${this.legs} legs.`); } } var myBird = new Animal("Bird"); myBird.showNameAndLegs();

Promisefunction sometimesWorks() { // note: all this function does is return a promise // the promise returns immediately to the caller return new Promise( function (resolve, reject) { // number of milliseconds to delay let delay = getRandomNum(1000, 3000); setTimeout(function(){ // whether it is successful or not let worked = !!Math.floor(getRandomNum(0, 2)); if(worked){ resolve('It worked!'); } else { reject('It failed'); } }, delay); }); }

PromisesometimesWorks().then( // if it is successful, it will come here function (data) { console.info(data); }, // if it fails it will come here function (err) { console.info(err); } ); console.info('Back from promise land');

What is the difference between var and let?

A. var is scoped to blocks and let is scoped to functions

B. let allows you to create a constant, var is for variables

C. let is scoped to blocks and var is scoped to functions

D. Nothing, let is the same as var

Default parameters

• Automatically assign a value to undefined parameters

• Always taken from left to right

Default parameter example

1 var add = (x=1, y=2) => x + y; 2 console.info(add(10));

ES2016 aka ES7

• array.prototype.includes

• Exponentiation operator **

How to use modern JS now?

• Use only the latest browsers

• Use a transpiler: Babel, Traceur, Closure, TypeScript

• Use Node.js

• https://kangax.github.io/compat-table/es6/

TypeScript

JavaScript Problems• No modules, only files

• No linkage

• No static checking

• Hard to refactor

• So Google created AtScript

The death of AtScript• Google forked TypeScript,

• Called it AtScript for @ signed used annotations

• Google and Microsoft engineers met

• Microsoft added some desired functionality to TypeScript

• TypeScript became the preferred language of Angular 2

TypeScript to JavaScript

• Use system.js to compile in browser

• Use typescript command

• Use npm/system.js/typescript to auto-compile

Types• Boolean

• Number

• String

• Array

• Tuple

• Enum

• Any

• Void

Interfaces• Functions

• Properties

• Arrays

• Extends other interfaces

• How to choose interface or class?

Decorators

• A proposed standard for ES2016

• Created by Yehuda Katz (Ember)

• Implemented in TypeScript

• Implement Angular’s Annotation

Annotation• A declarative way to add metadata to an object

• Three types:

• Type

• Field

• Class

Annotation Exampleimport {Component, OnInit} from 'angular2/core'; import {QuizService} from './quiz-service'; import {ROUTER_DIRECTIVES} from 'angular2/router'; @Component({ selector: 'quiz', templateUrl: './templates/quiz.html', directives: [ROUTER_DIRECTIVES], providers: [QuizService]}) export class QuizComponent implements OnInit { quizList:IQuizList[] = []; constructor(private _quizService:QuizService){ } ngOnInit() { this.getQuiz(); } getQuiz() { this._quizService.getQuizzes().then((quiz) => { this.quizList = quiz }, (error)=>console.log(error)); } }

Modules

• Any file containing a top-level import or export is considered a module

• Modules are executed within their own scope

• Modules are declarative

• Modules import one another using a module loader

tsconfig.json{ "compilerOptions": { "target": "es5", "module": "system", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false }, "exclude": [ "node_modules", "typings/main", "typings/main.d.ts" ] }

tsconfig.json

• target: compile to this version of JS

• module: module system to use

• moduleResolution: where modules are loaded

• sourceMap: should a source map be generated

tsconfig.json• emitDecoratorMetadata: set true to include the

decorator metadata, required for Angular 2

• experimentalDecorators: should we use ES7 style decorators

• removeComments: should comments be deleted

• noImplicitAny: set true if you want super strict typing, (you probably don’t want this)

• npm install -g typescript

• git clone https://github.com/Rockncoder/quizzer-start.git

• cd quizzer-start

• npm install

• npm start

Angular 2

Bootstrapping

• Angular apps built with components

• One component is chosen by the developer to kick off the app

• This process is known as bootstrapping

Main Parts• Metadata

• Component

• Template/View

• Data Binding

• Module

• Service

• Directive

• Dependency Injection

Metadata

• Metadata is extra information which gives angular more info

• @Component tells angular the class is a component

• @Directive tells angular the class is a directive

Component• A class with component metadata

• Responsible for a piece of the screen referred to as view.

• Template is a form HTML that tells angular how to render the component.

• Metadata tells Angular how to process a class

Componentimport {Component, OnInit} from 'angular2/core'import {QuizService} from './quiz-service'@Component({ selector: 'quiz', templateUrl: './templates/quiz.html', providers: [QuizService]}) export class QuizComponent implements OnInit { quizList: IQuizList[]; constructor(private _quizService:QuizService) { } ngOnInit() { this.getQuiz(); } getQuiz() { this.quizList = this._quizService.getQuizzes(); } }

Template/View• Is a way to describe a view using HTML

• Templates can be included with the component

• Or as an URL link to an HTML file

• Best practice is to use an HTML file

• The moduleId: module.id property sets the base for module-relative loading of the templateUrl.

moduleId

• The moduleId: module.id

• Sets the base for module-relative loading of the templateUrl.

Service

• “Substitutable objects that are wired together using dependency injection (DI)”

• Used to share code across app

• Lazily instantiated

Directives

Directive• A class with directive metadata

• Two kinds: attribute & structural

• Attribute directives alter the look or behavior of an existing element

• Structural directives alter the layout by adding, removing, and replacing elements in the DOM

• All structural directives begin with “*”

• A component is a directive with a view

Directives

Directive Purpose

*ngIf adds or removes part of the DOM

*ngFor implements a template

*ngSwitchCase teams up with ngSwitch & *ngSwitchDefault

Custom Directiveimport {Directive, ElementRef, Renderer, Input, OnInit} from 'angular2/core'; @Directive({ selector: '[sizer]'}) export class Sizer implements OnInit { @Input() sizer:string; element:ELementRef; renderer:Renderer; constructor(element:ElementRef, renderer:Renderer) { this.element = element; this.renderer = renderer; } ngOnInit() { this.renderer.setElementStyle(this.element.nativeElement, 'fontSize', this.sizer + '%'); } }

Component + Directiveimport {Directive, Component, ElementRef, Renderer} from ‘@angular/core'; import {Sizer} from './sizer'@Component({ selector: 'my-app', providers: [], template: ` <div> <p [sizer]="200">Butter{{name}}</p> </div> `, directives: [Sizer]}) export class App { constructor() { this.name = 'Monkey' } }

Dependency Injection• A way to supply a new instance of a class with the

fully-formed dependencies it needs

• Most dependencies are services

• Angular know which services a components by looking at the types of its constructor parameters

• Services are injected by an Injector which uses a Provider to create the service

Module

• Modules are optional but a best practice

• export tells TypeScript that the resource is a module available for other modules

• import tells TypeScript the resource in a module

• Angular ships a collection library modules

What is the difference between a component and a directive?

• Nothing, they are the same thing.

• A component is a directive with a view.

• A directive is a decorator and a component is an attribute.

• All of the above.

Lifecycle Hooks• ngOnChanges

• ngOnInit

• ngDoCheck

• ngAfterContentInit

• ngAfterContentCheck

• ngAfterViewInit

• ngAfterViewChecked

• ngOnDestroy

Forms

Forms in Angular

• Template-Driven Forms

• Model-Driven Forms

Data Binding

C/D Attribute Binding type

—> {{ value }} one-way

—> [property] = “value” property

<— (event) = “handler” event

<—> [(ng-model)] = “property” two-way

Using Forms

• Forms module must imported

• Forms use two-way binding via [(ngModel)]

• name attribute is required on form tags

NgForm

• Added to the form element automatically

• Holds the forms controls and their validity state

• Also has it own validity

ngModel Change-StateControl State If true If false

Visited ng-touched ng-untouched

Changed ng-dirty ng-pristine

Valid ng-valid ng-invalid

Control Classes

• *.pristine - true if the user has not touched the control

• *.touched - true if the user has left the control

• *.valid - true if the control is valid

template reference variable

• #<name>=“ngModel” (template ref. variable)

• ngModel is required here

• creates a variable named, <name>

• (it relates to the directive’s exportAs property)

t.r.v. properties

• .value

• .valid / .invalid

• .pristine / .dirty

• .touched / .untouched

Firebase

Installing Firebase

• npm i -S firebase angularfire2

• Add to app module and initialize

• Import into code

• Using firebase is different than hosting on it

Firebase settings

• Go to the Firebase console

• Click on Overview

• Click on “Add Firebase to your web app”

• Copy your config settings

Configure Firebase8 import {AngularFireModule} from "angularfire2"; 9 10 export const firebaseConfig = { 11 apiKey: "AxAxAxAxAxAxAxAxAxAxAxAxAxAxAxAxAxAxAxAx", 12 authDomain: “an-app-42.firebaseapp.com”, 13 databaseURL: "https:#//an-app-42.firebaseio.com", 14 storageBucket: "an-app-42.appspot.com", 15 messagingSenderId: "xxxxxxxxxxxx" 16 }; 17 18 @NgModule({ 19 imports: [ 20 BrowserModule, 21 FormsModule, 22 HttpModule, 23 AngularFireModule.initializeApp(firebaseConfig) 24 ], 25 declarations: [ 26 AppComponent 27 ], 28 providers: [], 29 bootstrap: [AppComponent] 30 })

RxJS

Reactive Extensions

• A library for building async and event-based programs using observable data streams

• Data streams can be from a file, web service, or user input

Use Rx for…• UI events like mouse move, button click

• Domain events like property changed, collection updated, etc.

• Infrastructure events like from file watcher, system and WMI events

• Integration events like a broadcast from a message bus or a push event from WebSockets API

Observable

• Emit the next element

• Throw an error

• Send a signal that streaming is finished

Observer

• Handle the next emitted element

• Handle errors

• Handle the end of streaming

Jasmine

Jasmine• Created by Pivotal Labs in 2010

• Current version 2.5.3

• JavaScript testing framework

• The default unit test for Angular

• Can test client and server code

describe() - Test Suite• describe() is a global Jasmine function

• Takes to parameters

• name of the test suite (string)

• implementation of the suite (function)

• Can be nested

describe()describe('App: Quizzer', () => { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ AppComponent ], imports: [ RouterTestingModule ] }); }); });

it() - Test Spec

• it() is a global Jasmine function

• Takes two parameters

• name of the spec (string)

• implementation of the spec (function)

it()

it(`should have as title 'Quizzer'`, async(() => { let fixture = TestBed.createComponent(AppComponent); let app = fixture.debugElement.componentInstance; expect(app.title).toEqual('Quizzer'); }));

expect() - Expectation• expect() is a global Jasmine function

• Jasmine’s version of assert()

• Takes one parameter

• The actual - value generated by code under test

• Is chained to a Matcher

Matcher

• Takes the output of the expect() function

• Takes one parameter

• The expected value

• Compares the expect and actual value using the logic of the matcher

expect()

let app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); expect(app).not.toBeUndefined(); expect(app.title).toEqual('Quizzer');

Matchers (part 1)Matcher Comparison

toBe() compares using ===

toEqual() works for literal variables and objects

toMatch() for regular expressions

toBeDefined() compares against 'undefined'

toBeUndefined() also compares against ‘undefined'

Matchers (part 2)Matcher Comparison

toBeNull() compares against null

toBeTruthy() truthy boolean casting

toBeFalsy() falsy boolean casting

toContain() finds an item in array

Matchers (part 3)Matcher Comparison

toBeLessThan() mathematical comparison

toBeGreaterThan() mathematical comparison

toBeCloseTo() precision math comparison

toThrow() should throw an exception

Angular’s MatchersMatcher Comparison

toBePromise() the value is a promise

toBeAnInstanceOf() an instance of an object

toHaveText() the element has the given text

toHaveCssClass() the element has the given CSS class

toHaveCssStyle() the element has the given CSS styles

toImplement() the class implements the given interface

Custom Matchersvar customMatchers = { toBeGoofy: function (util, customEqualityTesters) { return { compare: function (actual, expected) { if (expected === undefined) { expected = ''; } var result = {}; result.pass = util.equals(actual.hyuk, "gawrsh" + expected, customEqualityTesters); result.message = result.pass ? "Expected " + actual + " not to be quite so goofy" : "Expected " + actual + " to be goofy, but it was not very goofy"; return result; } }; } };

beforeEach()

• Setup function

• Called before each spec is executed

• A good place to add customer matchers

beforeEach()

beforeEach(function() { jasmine.addMatchers(customMatchers); });

this

• beforeEach sets the this construct to any empty object

• It is passed to each it() and afterEach()

• The modified this doesn’t flow thru from one it() to the next

afterEach()

• Teardown function

• Called after each spec is executed

Disabling suites & specs

• prepend an ‘x’

• to disable a suite change describe() to xdescribe()

• to disable a spec change it() to xit()

• They are not execute but appear in reporting

Dependency Injection is not Magic

• Dependency Injection (DI) is a core component of Angular

• It only means objects are instantiated somewhere else

• And supplied to your code when it needs them

• Angular calls DI a provider

providers@NgModule({ imports: TroyModules, declarations: [ AppComponent, AboutComponent, LoginComponent, QuizComponent, PlayerComponent, MixedPipe, BackcolorDirective, ModelComponent ], providers: [QuizService], bootstrap: [AppComponent] }) export class AppModule { }

Module InitializationKey Value

imports Modules (array)

declarations Components (array)

providers Services and other DI objects (array)

bootstrap the launch component

Unit Test & DI

• When unit testing your app you ask Angular for just enough parts to make it work

• Angular uses DI to do this

Unit Tests & Providersdescribe('Router', () => { beforeEach(() => { // acts like NgModule TestBed.configureTestingModule({ imports: [ RouterTestingModule, AppRoutingModule ], declarations: [ AppComponent, AboutComponent, LoginComponent ], providers: [ {provide: APP_BASE_HREF, useValue: '/'} ] }); });

Links

• https://angular.io/

• https://material.angular.io/

• https://github.com/systemjs/systemjs

• https://github.com/angular/angularfire2

• http://blog.angular-university.io/angular-2-firebase/

Links• http://www.sitepoint.com/angular-2-mockbackend/

• https://auth0.com/blog/2015/09/03/angular2-series-working-with-pipes/

• https://developers.livechatinc.com/blog/testing-angular-2-apps-routeroutlet-and-http/

• https://medium.com/google-developer-experts/angular-2-introduction-to-new-http-module-1278499db2a0#.xey81v6eq

Summary

• Angular 2 is simpler than AngularJS

• TypeScript is the preferred language for Angular 2

• The framework is made to be easily testable

Recommended