CoWork SouthBay 22 + 23 July 2017
Angular
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
• lynda.com Author!

Kotlin for Java Developers
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 Versions
app command my version
git git —version 2.12.2
node.js node -v v7.9.0
npm npm —v 5.3.0
@angular/cli ng -v 1.2.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 CLI
Tool 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 Components
Component Command
Class ng g class my-new-class
Component ng g component my-new-component
Directive ng g directive my-new-directive
Enum ng g enum my-new-enum
Interface ng g interface my-new-interface
Module ng g module my-module
Pipe ng g pipe my-new-pipe
Service ng g service my-new-service
CLI 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
name examples
• contact-details.component.ts
• results-list.component.spec.ts
• convert2k.pipe.ts
• git-hub.service.ts
npm
npm
• The package manager for JavaScript
• npm requires a file, package.json, in the app root
• requires node.js because it is written in JavaScript
• doesn’t officially 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>
• or npm run <command> <args>
• to abort use control-c
• start and test commands don’t need “run”
• npm start OR npm test
What’s in our package.json?
• @angular - Angular components
• core-js - Modular standard library for JavaScript
• rxjs - Reactive extensions library
• zone.js - Implements Zones for JavaScript
Webpack
Webpack
• Module bundler
• A dependency of @angular/cli
• Replaces System.JS, Browserify, and others
• Works with JS, CSS, and HTML
• Minifies, concatenates, and bundles
How?
• Webpack starts at your app’s entry point
• It makes a graph of all dependencies
• It then bundles them together into an output file
• (Directed Acyclic Graph or DAG for short)
Loaders
• Goal: Webpack handler loading of all of your app’s
assets
• Every file is a module
• Webpack only understands only JavaScript
• Loaders transform files into modules
Rules
• test: Identifies the file’s type
• use: Transform the file with a plugin loader
Example #1
module: {
rules: [
{
test: /.jsx*$/,
exclude: [/node_modules/, /.+.config.js/],
loader: 'babel-loader',
},
Example #2{
test: /.css$/,
use: [
{
loader: 'style-loader',
options: {
sourceMap: true
}
},
{
loader: 'css-loader',
options: {
modules: true,
importLoaders: 1,
localIdentName: '[path]___[name]__[local]___[hash:base64:5]'
}
},
{
loader: 'postcss-loader'
}
],
},
JavaScript
ECMAScript Versions
Version Date
ES1 June 1997
ES2 June 1998
ES3 December 1999
ES4 DOA 2006
ES5 December 2009
ES2015 / ES6 June 2015
ES2016 / ES7 2016
Collection Operators
• .isArray()
• .every()
• .forEach()
• .indexOf()
• .lastIndexOf()
• .some()
• .map()
• .reduce()
• .filter()
map
let 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 elements

let nums2 = nums.map((elem) => elem * 2);

console.log(nums2);
/// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40]


filter
let 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 test

let nums3 = nums.filter((elem) => !!(elem % 2));

console.log(nums3);
/// [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
reduce
let 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 strings

let letters2 = letters.reduce((previous, current) => previous + current);

console.log(letters2);
/// ABCDEFGHIJK



// reduceRight does the same but goes from right to left

let letters3 = letters.reduceRight((previous, current) => previous + current);

console.log(letters3);
/// KJIHGFEDCBA

let
• let allows us to create a block scoped variables
• they live and die within their curly braces
• var is considered deprecated
• 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 braces

let 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
const
const name = 'Troy';

console.info(`My name is ${name}`);

// the line below triggers a type error

name = '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 functions
• Succinct syntax
• Doesn’t bind its own this, arguments, or super
• Facilitate a more functional style of coding
• Can’t be used as constructors
Arrow functions
• When only one parameter, parenthesis optional
• When zero or more than one parameter,
parenthesis required
Arrow function
let 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)}`);

this
• this is handled different in arrow functions
• In anonymous function this is bound to the global
object
• In arrow function this is what it was in the outer
scope
Destructuring
• Maps the data on the right side of the equals sign
to the variables on the left
• The data type decides the way values are mapped
• It is either object or array destructuring
Object Destructuring
16// this is a demo of the power of destructuring
17// we have two objects with the same 3 properties
18 const binary = {kb: 1024, mb: 1048576, gb: 1073741824};
19 const digital = {kb: 1000, mb: 1000000, gb: 1000000000};
20// We use a ternary statement to choose which object
21// assign properties based on their property names
22 const {kb, mb, gb} = (useBinary) ? binary : digital;
Array Destructuring
5
6 let [param1, bob, key] = ['first', 'second', '3rd'];
7 console.info(`param1 = ${param1}, bob = ${bob}, key = ${key}`);
8 // param1 = first, bob = second, key = 3rd
Spread syntax
• Expands an expression in places where multiple
arguments, elements, or variables are expected
The spread operator
11
12 // the spread operator
13 const myArray = ['Bob', 'Sue', 'Fido'];
14 function printFamily(person1, person2, pet) {
15 console.info(`Person 1: ${person1}, Person 2: ${person2}, and their pet: ${pet}`);
16 }
17 printFamily(...myArray);
18 // Person 1: Bob, Person 2: Sue, and their pet: Fido
19
Class
• Syntactic sugar over JavaScript use of function
constructors
• JavaScript uses proto-typical inheritance
• If a class extends another, it must include super()
as first instruction in its constructor
• Only create a constructor if it does something
Class
• Syntactic sugar over JavaScript use of function
constructors
• JavaScript uses proto-typical inheritance
• If a class extends another, it must include super()
as first instruction in its constructor
• Only create a constructor if it does something
import
• Imports functions, objects, or primitives from other
files
• import <name> from “<module name>”;
• import {name } from “<module name>”;
• import * as Greetings from “<module name>”;
• relative path indicates not an npm package
export
• export <var a>
• export {a, b};
export default
• only one per file
• common pattern for libraries
• const Greetings = {sayHi, sayBye};
• export default Greetings;
• export default {sayHi, sayBye};
Importing Old School JS
• Many JS libraries don’t support the new syntax
• How do we use them?
• import ‘jquery’;
ES2016 aka ES7
• array.prototype.includes
• Exponentiation operator **
How to use modern JS now?
• Use only the latest browsers
• Use Node.js
• Use a transpiler: Closure, Babel, TypeScript
• (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 is the preferred language of Angular
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 Example
import {Component, OnInit} from ‘@angular/core';

import {QuizService} from './quiz-service';

import {ROUTER_DIRECTIVES} from ‘@angular/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
• 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)
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
• New versions of JavaScript (ES5, ES6, ES2016)
• Lots of new browser capabilities
• Transpilers like TypeScript and Babel
• Cool libraries like RxJS and Zone
• No longer necessary for Angular to do everything
Angular
Deleted from Angular
• $scope
• Data Definition Object
• angular module
• controllers
• jqLite / jQuery
Main Parts
• Module
• Component
• Template
• Data binding
• Metadata
• Service
• Directive
• Dependency Injection
Bootstrapping
• Angular apps built with components
• One component is chosen to kick off the app
• This process is known as bootstrapping
• Our app begins in file main.ts
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
Component
import {Component, OnInit} from ‘@angular/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
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 Directive
import {Directive, ElementRef, Renderer, Input, OnInit} from ‘@angular/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 + Directive
import {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
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 Initialization
Key Value
imports Modules (array)
declarations Components (array)
providers Services and other DI objects (array)
bootstrap the launch component
Lifecycle Hooks
• ngOnChanges
• ngOnInit
• ngDoCheck
• ngAfterContentInit
• ngAfterContentCheck
• ngAfterViewInit
• ngAfterViewChecked
• ngOnDestroy
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-State
Control 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
Firebase commands
Command 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 Steps
1. 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 )
Configure Firebase
8 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
Angular Material
• npm i -S @angular/material
• npm i -S hammerjs
• Add to app.module.ts

import { MaterialModule } from '@angular/material';

import ‘hammerjs';

(add to imports)
• Add to global css

@import '~@angular/material/core/theming/prebuilt/
deeppurple-amber.css';

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 Matchers
Matcher 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 Matchers
var 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
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 & Providers
describe('Router', () => {

beforeEach(() => {

// acts like NgModule

TestBed.configureTestingModule({

imports: [

RouterTestingModule, AppRoutingModule

],

declarations: [

AppComponent, AboutComponent, LoginComponent

],

providers: [

{provide: APP_BASE_HREF, useValue: '/'}

]

});

});

Add Style to Your App
Google Roboto Font
• This part isn’t necessary
• But it is a nice font
• Gives your website that authentic Google look
src/index.html
index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Angular MDL</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto:100"
rel="stylesheet"
type="text/css">
</head>
<body>
<app-root>Loading...</app-root>
</body>
</html>
src/styles.css
styles.css
/* You can add global styles to this file, and also import other style files */
body {
font-family: Roboto, sans-serif;
font-size: 18px;
}
Material Icons
Material Icons
• Simple, modern, friendly, sometimes quirky icons
• Created using Google’s design guidelines
• Depict universal concepts in minimal form
• Legible in both large and small sizes
• Optimized for beauty
Licensing
• Licensed under Apache License Version 2.0
• You are free to remix and re-share
• You may give attribution, but not required
• You are not allowed to sell them
Downloading
• Download the latest from archive (~60mb)
• git clone http://github.com/google/material-design-
icons/
• npm install material-design-icons
Google Web Fonts
• Self-host (load fonts & setup CSS rules)
• Use Google Web Fonts
• <link href="https://fonts.googleapis.com/icon?
family=Material+Icons" rel="stylesheet">
Ligature Support
Browser Version
Chrome 11
Firefox 3.5
Internet Explorer (IE) 10
Opera 15
Safari 5
Android Browser 3.0
Mobile Safari iOS 4.2
Displaying Icons
• <i class=“material-icons">face</i>
• <i class=“material-icons">&#xE87C;</i>
Rendering
• Best to copy the Unicode character 😼
• Browsers can’t render Unicode (U+1F63C)
• Browser can usually only render 4 digit hex codes
so the above code won’t display
Angular Material
Why?
• There are already a lot of CSS frameworks
• Including Bootstrap and Foundation 3
• Why create a new one?
Components > Classes
• Less HTML markup
• Less errors
• Better tool support
• Help end <div> tag insanity
Installation
• npm install --save @angular/material @angular/cdk
@angular/animations
• Import BrowserAnimation/NoopAnimation module
• Import component modules
• Include a theme
• Import hammerjs
Installation
• npm install --save @angular/material @angular/cdk
• npm install --save @angular/animations
• Import either BrowserAnimation or NoopAnimation
module
• Import component modules
• Include a theme
hammer.js
• Adds support for touch gestures
• Removes 300ms delay from clicks
• npm install --save hammerjs
• Import hammerjs in app.module.ts
Themes
• Add one to your styles.css
• @import '~@angular/material/core/theming/prebuilt/
deeppurple-amber.css';
• @import '~@angular/material/core/theming/prebuilt/indigo-
pink.css';
• @import '~@angular/material/core/theming/prebuilt/pink-
bluegrey.css';
• @import '~@angular/material/core/theming/prebuilt/purple-
green.css';
Feature Status
Feature Status
button available
cards available
checkbox available
radio available
input available
sidenav available
toolbar available
Feature Status
Feature Status
list available
grid-list available
icon available
progress-spinner available
progress-bar available
tabs available
slide-toggle available
Feature Status
Feature Status
button-toggle available
slider available
menu available
tooltip available
ripples available
dialog available
snackbar / toast available
Feature Status
Feature Status
select available
textarea available
autocomplete available
chips available
theming available
typography not started
Feature Status
Feature Status
fab speed-dial not started
fab toolbar not started
bottom-sheet not started
bottom-nav not started
virtual repeat Q4 2017
datepicker available
data-table available
Feature Status
Feature Status
stepper in-progress
tree in-progress
layout see angular/flex-layout
Wrapping Up
Links
• https://angular.io/
• https://firebase.google.com/
• https://material.angular.io/
• https://github.com/angular/angularfire2
Links
• https://github.com/angular/angularfire2
• http://blog.angular-university.io/angular-2-firebase/
• https://auth0.com/blog/2015/09/03/angular2-series-
working-with-pipes/
• https://developers.livechatinc.com/blog/testing-
angular-2-apps-routeroutlet-and-http/
Summary
• Angular is simpler than AngularJS
• TypeScript is the preferred language for Angular
• The framework is made to be easily testable

Angular Weekend

  • 1.
    CoWork SouthBay 22+ 23 July 2017 Angular Weekend Workshop
  • 3.
    Troy Miles • TroyMiles aka the RocknCoder • Over 38 years of programming experience • Speaker and author • bit.ly/rc-jquerybook • rockncoder@gmail.com • @therockncoder • lynda.com Author!

  • 5.
    Kotlin for JavaDevelopers
  • 6.
    Agenda: Day One •Overview • Angular CLI • Webpack • Modern JavaScript • TypeScript • Components / Views • Router • Data Binding • Dependency Injection • Services
  • 7.
    Agenda: Day Two •HTTP • Forms • Pipes • Directives • RxJS • Unit Testing • Angular Material • Summary
  • 8.
    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
  • 9.
    Check Versions app commandmy version git git —version 2.12.2 node.js node -v v7.9.0 npm npm —v 5.3.0 @angular/cli ng -v 1.2.3 firebase firebase version 3.3.0
  • 10.
    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
  • 11.
    Angular CLI Tool Command NewApp 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
  • 12.
    Create New Components ComponentCommand Class ng g class my-new-class Component ng g component my-new-component Directive ng g directive my-new-directive Enum ng g enum my-new-enum Interface ng g interface my-new-interface Module ng g module my-module Pipe ng g pipe my-new-pipe Service ng g service my-new-service
  • 13.
    CLI 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
  • 14.
    name examples • contact-details.component.ts •results-list.component.spec.ts • convert2k.pipe.ts • git-hub.service.ts
  • 15.
  • 16.
    npm • The packagemanager for JavaScript • npm requires a file, package.json, in the app root • requires node.js because it is written in JavaScript • doesn’t officially stand for anything • https://www.npmjs.com/
  • 17.
    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
  • 18.
    package.json • license -type of license granted to users of the package • scripts - commands • dependencies - packages for production • devDependencies - packages for development
  • 19.
    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
  • 20.
    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
  • 21.
    install • The installadds 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
  • 22.
    run-script • npm run-script<command> <args> • or npm run <command> <args> • to abort use control-c • start and test commands don’t need “run” • npm start OR npm test
  • 23.
    What’s in ourpackage.json? • @angular - Angular components • core-js - Modular standard library for JavaScript • rxjs - Reactive extensions library • zone.js - Implements Zones for JavaScript
  • 24.
  • 25.
    Webpack • Module bundler •A dependency of @angular/cli • Replaces System.JS, Browserify, and others • Works with JS, CSS, and HTML • Minifies, concatenates, and bundles
  • 26.
    How? • Webpack startsat your app’s entry point • It makes a graph of all dependencies • It then bundles them together into an output file • (Directed Acyclic Graph or DAG for short)
  • 27.
    Loaders • Goal: Webpackhandler loading of all of your app’s assets • Every file is a module • Webpack only understands only JavaScript • Loaders transform files into modules
  • 28.
    Rules • test: Identifiesthe file’s type • use: Transform the file with a plugin loader
  • 29.
    Example #1 module: { rules:[ { test: /.jsx*$/, exclude: [/node_modules/, /.+.config.js/], loader: 'babel-loader', },
  • 30.
    Example #2{ test: /.css$/, use:[ { loader: 'style-loader', options: { sourceMap: true } }, { loader: 'css-loader', options: { modules: true, importLoaders: 1, localIdentName: '[path]___[name]__[local]___[hash:base64:5]' } }, { loader: 'postcss-loader' } ], },
  • 31.
  • 32.
    ECMAScript Versions Version Date ES1June 1997 ES2 June 1998 ES3 December 1999 ES4 DOA 2006 ES5 December 2009 ES2015 / ES6 June 2015 ES2016 / ES7 2016
  • 33.
    Collection Operators • .isArray() •.every() • .forEach() • .indexOf() • .lastIndexOf() • .some() • .map() • .reduce() • .filter()
  • 34.
    map let 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 elements
 let nums2 = nums.map((elem) => elem * 2);
 console.log(nums2); /// [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40] 

  • 35.
    filter let 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 test
 let nums3 = nums.filter((elem) => !!(elem % 2));
 console.log(nums3); /// [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
  • 36.
    reduce let 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 strings
 let letters2 = letters.reduce((previous, current) => previous + current);
 console.log(letters2); /// ABCDEFGHIJK
 
 // reduceRight does the same but goes from right to left
 let letters3 = letters.reduceRight((previous, current) => previous + current);
 console.log(letters3); /// KJIHGFEDCBA

  • 37.
    let • let allowsus to create a block scoped variables • they live and die within their curly braces • var is considered deprecated • best practice is to use let instead of var
  • 38.
    let // let allowsus to create block scoped variables
 // they live and die within the curly braces
 let val = 2;
 console.info(`val = ${val}`);
 {
 let val = 59;
 console.info(`val = ${val}`);
 }
 console.info(`val = ${val}`);
 

  • 39.
    const • const createsa 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
  • 40.
    const const name ='Troy';
 console.info(`My name is ${name}`);
 // the line below triggers a type error
 name = 'Miles';

  • 41.
    Template strings • Definedby 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)
  • 42.
    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.`);
 

  • 43.
    Arrow functions • Succinctsyntax • Doesn’t bind its own this, arguments, or super • Facilitate a more functional style of coding • Can’t be used as constructors
  • 44.
    Arrow functions • Whenonly one parameter, parenthesis optional • When zero or more than one parameter, parenthesis required
  • 45.
    Arrow function let 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)}`);

  • 46.
    this • this ishandled different in arrow functions • In anonymous function this is bound to the global object • In arrow function this is what it was in the outer scope
  • 47.
    Destructuring • Maps thedata on the right side of the equals sign to the variables on the left • The data type decides the way values are mapped • It is either object or array destructuring
  • 48.
    Object Destructuring 16// thisis a demo of the power of destructuring 17// we have two objects with the same 3 properties 18 const binary = {kb: 1024, mb: 1048576, gb: 1073741824}; 19 const digital = {kb: 1000, mb: 1000000, gb: 1000000000}; 20// We use a ternary statement to choose which object 21// assign properties based on their property names 22 const {kb, mb, gb} = (useBinary) ? binary : digital;
  • 49.
    Array Destructuring 5 6 let[param1, bob, key] = ['first', 'second', '3rd']; 7 console.info(`param1 = ${param1}, bob = ${bob}, key = ${key}`); 8 // param1 = first, bob = second, key = 3rd
  • 50.
    Spread syntax • Expandsan expression in places where multiple arguments, elements, or variables are expected
  • 51.
    The spread operator 11 12// the spread operator 13 const myArray = ['Bob', 'Sue', 'Fido']; 14 function printFamily(person1, person2, pet) { 15 console.info(`Person 1: ${person1}, Person 2: ${person2}, and their pet: ${pet}`); 16 } 17 printFamily(...myArray); 18 // Person 1: Bob, Person 2: Sue, and their pet: Fido 19
  • 52.
    Class • Syntactic sugarover JavaScript use of function constructors • JavaScript uses proto-typical inheritance • If a class extends another, it must include super() as first instruction in its constructor • Only create a constructor if it does something
  • 53.
    Class • Syntactic sugarover JavaScript use of function constructors • JavaScript uses proto-typical inheritance • If a class extends another, it must include super() as first instruction in its constructor • Only create a constructor if it does something
  • 54.
    import • Imports functions,objects, or primitives from other files • import <name> from “<module name>”; • import {name } from “<module name>”; • import * as Greetings from “<module name>”; • relative path indicates not an npm package
  • 55.
    export • export <vara> • export {a, b};
  • 56.
    export default • onlyone per file • common pattern for libraries • const Greetings = {sayHi, sayBye}; • export default Greetings; • export default {sayHi, sayBye};
  • 57.
    Importing Old SchoolJS • Many JS libraries don’t support the new syntax • How do we use them? • import ‘jquery’;
  • 58.
    ES2016 aka ES7 •array.prototype.includes • Exponentiation operator **
  • 59.
    How to usemodern JS now? • Use only the latest browsers • Use Node.js • Use a transpiler: Closure, Babel, TypeScript • (https://kangax.github.io/compat-table/es6/)
  • 60.
  • 61.
    JavaScript Problems • Nomodules, only files • No linkage • No static checking • Hard to refactor • So Google created AtScript
  • 62.
    The death ofAtScript • Google forked TypeScript, • Called it AtScript for @ signed used annotations • Google and Microsoft engineers met • Microsoft added some desired functionality to TypeScript • TypeScript is the preferred language of Angular
  • 63.
    Types • Boolean • Number •String • Array • Tuple • Enum • Any • Void
  • 64.
    Interfaces • Functions • Properties •Arrays • Extends other interfaces • How to choose interface or class?
  • 65.
    Decorators • A proposedstandard for ES2016 • Created by Yehuda Katz (Ember) • Implemented in TypeScript • Implement Angular’s Annotation
  • 66.
    Annotation • A declarativeway to add metadata to an object • Three types: • Type • Field • Class
  • 67.
    Annotation Example import {Component,OnInit} from ‘@angular/core';
 import {QuizService} from './quiz-service';
 import {ROUTER_DIRECTIVES} from ‘@angular/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));
 }
 }
  • 68.
    Modules • Any filecontaining 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
  • 69.
    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"
 ]
 }
  • 70.
    tsconfig.json • target: compileto this version of JS • module: module system to use • moduleResolution: where modules are loaded • sourceMap: should a source map be generated
  • 71.
    tsconfig.json • emitDecoratorMetadata: settrue to include the decorator metadata, required for Angular • 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)
  • 72.
    AngularJS • Created byMiško Hevery and Adam Abrons in 2009 • JavaScript MVC • Declarative programming for UI • Imperative programming for business logic
  • 73.
    AngularJS Main Parts •Module • Views/Controllers • Services • Directives • Filters
  • 74.
    Since 2009 • Newversions of JavaScript (ES5, ES6, ES2016) • Lots of new browser capabilities • Transpilers like TypeScript and Babel • Cool libraries like RxJS and Zone • No longer necessary for Angular to do everything
  • 75.
  • 76.
    Deleted from Angular •$scope • Data Definition Object • angular module • controllers • jqLite / jQuery
  • 77.
    Main Parts • Module •Component • Template • Data binding • Metadata • Service • Directive • Dependency Injection
  • 78.
    Bootstrapping • Angular appsbuilt with components • One component is chosen to kick off the app • This process is known as bootstrapping • Our app begins in file main.ts
  • 79.
    Metadata • Metadata isextra information which gives angular more info • @Component tells angular the class is a component • @Directive tells angular the class is a directive
  • 80.
    Component • A classwith 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
  • 81.
    Component import {Component, OnInit}from ‘@angular/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();
 }
 }
  • 82.
    Template/View • Is away 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.
  • 83.
    moduleId • The moduleId:module.id • Sets the base for module-relative loading of the templateUrl.
  • 84.
    Service • “Substitutable objectsthat are wired together using dependency injection (DI)” • Used to share code across app • Lazily instantiated
  • 85.
    Directive • A classwith 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
  • 86.
    Directives Directive Purpose *ngIf addsor removes part of the DOM *ngFor implements a template *ngSwitchCase teams up with ngSwitch & *ngSwitchDefault
  • 87.
    Custom Directive import {Directive,ElementRef, Renderer, Input, OnInit} from ‘@angular/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 + '%');
 }
 }
  • 88.
    Component + Directive import{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'
 }
 }
  • 89.
    Dependency Injection • Away 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
  • 90.
    Dependency Injection isnot 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
  • 91.
  • 92.
    Module Initialization Key Value importsModules (array) declarations Components (array) providers Services and other DI objects (array) bootstrap the launch component
  • 93.
    Lifecycle Hooks • ngOnChanges •ngOnInit • ngDoCheck • ngAfterContentInit • ngAfterContentCheck • ngAfterViewInit • ngAfterViewChecked • ngOnDestroy
  • 94.
    Forms in Angular •Template-Driven Forms • Model-Driven Forms
  • 95.
    Data Binding C/D AttributeBinding type —> {{ value }} one-way —> [property] = “value” property <— (event) = “handler” event <—> [(ng-model)] = “property” two-way
  • 96.
    Using Forms • Formsmodule must imported • Forms use two-way binding via [(ngModel)] • name attribute is required on form tags
  • 97.
    NgForm • Added tothe form element automatically • Holds the forms controls and their validity state • Also has it own validity
  • 98.
    ngModel Change-State Control StateIf true If false Visited ng-touched ng-untouched Changed ng-dirty ng-pristine Valid ng-valid ng-invalid
  • 99.
    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
  • 100.
    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)
  • 101.
    t.r.v. properties • .value •.valid / .invalid • .pristine / .dirty • .touched / .untouched
  • 102.
  • 103.
    Installing Firebase • npmi -S firebase angularfire2 • Add to app module and initialize • Import into code • Using firebase is different than hosting on it
  • 104.
    Firebase settings • Goto the Firebase console • Click on Overview • Click on “Add Firebase to your web app” • Copy your config settings
  • 105.
    Firebase commands Command What? firebaselogin 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
  • 106.
    Firebase Steps 1. Createproject 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 )
  • 107.
    Configure Firebase 8 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 })
  • 108.
  • 109.
    Reactive Extensions • Alibrary for building async and event-based programs using observable data streams • Data streams can be from a file, web service, or user input
  • 110.
    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
  • 111.
    Observable • Emit thenext element • Throw an error • Send a signal that streaming is finished
  • 112.
    Observer • Handle thenext emitted element • Handle errors • Handle the end of streaming
  • 114.
    Angular Material • npmi -S @angular/material • npm i -S hammerjs • Add to app.module.ts
 import { MaterialModule } from '@angular/material';
 import ‘hammerjs';
 (add to imports) • Add to global css
 @import '~@angular/material/core/theming/prebuilt/ deeppurple-amber.css';

  • 115.
  • 116.
    Jasmine • Created byPivotal Labs in 2010 • Current version 2.5.3 • JavaScript testing framework • The default unit test for Angular • Can test client and server code
  • 117.
    describe() - TestSuite • describe() is a global Jasmine function • Takes to parameters • name of the test suite (string) • implementation of the suite (function) • Can be nested
  • 118.
    describe() describe('App: Quizzer', ()=> { beforeEach(() => { TestBed.configureTestingModule({ declarations: [ AppComponent ], imports: [ RouterTestingModule ] }); }); });
  • 119.
    it() - TestSpec • it() is a global Jasmine function • Takes two parameters • name of the spec (string) • implementation of the spec (function)
  • 120.
    it() it(`should have astitle 'Quizzer'`, async(() => { let fixture = TestBed.createComponent(AppComponent); let app = fixture.debugElement.componentInstance; expect(app.title).toEqual('Quizzer'); }));
  • 121.
    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
  • 122.
    Matcher • Takes theoutput of the expect() function • Takes one parameter • The expected value • Compares the expect and actual value using the logic of the matcher
  • 123.
    expect() let app =fixture.debugElement.componentInstance; expect(app).toBeTruthy(); expect(app).not.toBeUndefined(); expect(app.title).toEqual('Quizzer');
  • 124.
    Matchers (part 1) MatcherComparison toBe() compares using === toEqual() works for literal variables and objects toMatch() for regular expressions toBeDefined() compares against 'undefined' toBeUndefined() also compares against ‘undefined'
  • 125.
    Matchers (part 2) MatcherComparison toBeNull() compares against null toBeTruthy() truthy boolean casting toBeFalsy() falsy boolean casting toContain() finds an item in array
  • 126.
    Matchers (part 3) MatcherComparison toBeLessThan() mathematical comparison toBeGreaterThan() mathematical comparison toBeCloseTo() precision math comparison toThrow() should throw an exception
  • 127.
    Angular’s Matchers Matcher 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
  • 128.
    Custom Matchers var 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; } }; } };
  • 129.
    beforeEach() • Setup function •Called before each spec is executed • A good place to add customer matchers
  • 130.
  • 131.
    this • beforeEach setsthe 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
  • 132.
    afterEach() • Teardown function •Called after each spec is executed
  • 133.
    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
  • 134.
    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
  • 135.
    Unit Tests &Providers describe('Router', () => {
 beforeEach(() => {
 // acts like NgModule
 TestBed.configureTestingModule({
 imports: [
 RouterTestingModule, AppRoutingModule
 ],
 declarations: [
 AppComponent, AboutComponent, LoginComponent
 ],
 providers: [
 {provide: APP_BASE_HREF, useValue: '/'}
 ]
 });
 });

  • 136.
    Add Style toYour App
  • 137.
    Google Roboto Font •This part isn’t necessary • But it is a nice font • Gives your website that authentic Google look
  • 138.
    src/index.html index.html <!doctype html> <html> <head> <meta charset="utf-8"> <title>AngularMDL</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <link href="https://fonts.googleapis.com/css?family=Roboto:100" rel="stylesheet" type="text/css"> </head> <body> <app-root>Loading...</app-root> </body> </html>
  • 139.
    src/styles.css styles.css /* You canadd global styles to this file, and also import other style files */ body { font-family: Roboto, sans-serif; font-size: 18px; }
  • 140.
  • 141.
    Material Icons • Simple,modern, friendly, sometimes quirky icons • Created using Google’s design guidelines • Depict universal concepts in minimal form • Legible in both large and small sizes • Optimized for beauty
  • 142.
    Licensing • Licensed underApache License Version 2.0 • You are free to remix and re-share • You may give attribution, but not required • You are not allowed to sell them
  • 143.
    Downloading • Download thelatest from archive (~60mb) • git clone http://github.com/google/material-design- icons/ • npm install material-design-icons
  • 144.
    Google Web Fonts •Self-host (load fonts & setup CSS rules) • Use Google Web Fonts • <link href="https://fonts.googleapis.com/icon? family=Material+Icons" rel="stylesheet">
  • 145.
    Ligature Support Browser Version Chrome11 Firefox 3.5 Internet Explorer (IE) 10 Opera 15 Safari 5 Android Browser 3.0 Mobile Safari iOS 4.2
  • 146.
    Displaying Icons • <iclass=“material-icons">face</i> • <i class=“material-icons">&#xE87C;</i>
  • 147.
    Rendering • Best tocopy the Unicode character 😼 • Browsers can’t render Unicode (U+1F63C) • Browser can usually only render 4 digit hex codes so the above code won’t display
  • 148.
  • 149.
    Why? • There arealready a lot of CSS frameworks • Including Bootstrap and Foundation 3 • Why create a new one?
  • 150.
    Components > Classes •Less HTML markup • Less errors • Better tool support • Help end <div> tag insanity
  • 151.
    Installation • npm install--save @angular/material @angular/cdk @angular/animations • Import BrowserAnimation/NoopAnimation module • Import component modules • Include a theme • Import hammerjs
  • 152.
    Installation • npm install--save @angular/material @angular/cdk • npm install --save @angular/animations • Import either BrowserAnimation or NoopAnimation module • Import component modules • Include a theme
  • 153.
    hammer.js • Adds supportfor touch gestures • Removes 300ms delay from clicks • npm install --save hammerjs • Import hammerjs in app.module.ts
  • 154.
    Themes • Add oneto your styles.css • @import '~@angular/material/core/theming/prebuilt/ deeppurple-amber.css'; • @import '~@angular/material/core/theming/prebuilt/indigo- pink.css'; • @import '~@angular/material/core/theming/prebuilt/pink- bluegrey.css'; • @import '~@angular/material/core/theming/prebuilt/purple- green.css';
  • 155.
    Feature Status Feature Status buttonavailable cards available checkbox available radio available input available sidenav available toolbar available
  • 156.
    Feature Status Feature Status listavailable grid-list available icon available progress-spinner available progress-bar available tabs available slide-toggle available
  • 157.
    Feature Status Feature Status button-toggleavailable slider available menu available tooltip available ripples available dialog available snackbar / toast available
  • 158.
    Feature Status Feature Status selectavailable textarea available autocomplete available chips available theming available typography not started
  • 159.
    Feature Status Feature Status fabspeed-dial not started fab toolbar not started bottom-sheet not started bottom-nav not started virtual repeat Q4 2017 datepicker available data-table available
  • 160.
    Feature Status Feature Status stepperin-progress tree in-progress layout see angular/flex-layout
  • 161.
  • 162.
    Links • https://angular.io/ • https://firebase.google.com/ •https://material.angular.io/ • https://github.com/angular/angularfire2
  • 163.
    Links • https://github.com/angular/angularfire2 • http://blog.angular-university.io/angular-2-firebase/ •https://auth0.com/blog/2015/09/03/angular2-series- working-with-pipes/ • https://developers.livechatinc.com/blog/testing- angular-2-apps-routeroutlet-and-http/
  • 164.
    Summary • Angular issimpler than AngularJS • TypeScript is the preferred language for Angular • The framework is made to be easily testable