Angular 2 Weekend Workshop

Post on 16-Apr-2017

794 views 0 download

Transcript of Angular 2 Weekend Workshop

Angular 2.0 Weekend WorkshopCowork South Bay 22 + 23 Oct 2016

Troy MilesTroy Miles

Speaker and author

https://therockncoder.com/

rockncoder@gmail.com

@therockncoder

@therockncoderPlease follow me on twitter

Links

Slides:

http://www.slideshare.net/rockncoder/angular-2-weekend-workshop

Code:

https://github.com/Rockncoder/quizzer-start

Day One Agenda

Installation

Angular 2 Overview

ES5 / ES6

TypeScript

Components / Views

Component Router

Data binding

Dependency Injection

Services

Http

Day Two Agenda

Forms

Pipes

Directives

RxJS

Unit Testing

Angular Material

The Upgrade Adapter

Summary

Things we won’t cover

Backend - We will be focused on the front-end

Security - Our code will be open and insecure

Other languages - TypeScript is the language used by the core team

Why the BIG change?

2009 C.E.

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

ECMAScript VersionsVersion Date

ES1 June 1997ES2 June 1998ES3 December 1999ES4 DOA 2006ES5 December 2009

ES6/ES2015 June 2015ES2016 2016

AngularJSCreated 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

No longer necessary for Angular to do everything

Getting startednpm 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 -

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 any npm command or package?

A. https://angular.io/

B. https://www.npmjs.com/

C. https://angularjs.org/

D. https://nodejs.org/

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

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

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

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

Angular 2

Its Angular 2, not AngularJS 2

ES5

ES6

CoffeeScript

Dart

TypeScript

Deleted from Angular 2

$scope

Data Definition Object

angular module

controllers

jqLite / jQuery

Main bits

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 modeVariables 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

Falsey

Type Results

null FALSE

undefined FALSE

Number if 0 or NaN, FALSE

String if length = 0, FALSE

Object TRUE

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);

JSONJSON 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 sample{ "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.stringify()

B. JSON.parse()

C. Math.obj()

D. .toString()

ES6 (ES2015)

ES6 aka ES2015

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) 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)}`);

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 exits the loop and continue goes immediately to the top of the loop

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

for-offor 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-offor (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}`); }

Classes// 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 is scoped to blocks and var is scoped to functions

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

D. Nothing, let is the same as var

Default parameters

Automatically assign a value to undefined parameters

Always taken from left to right

default value 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 ES6 today?

Use only the latest browsers

Use a transpiler: Babel, Traceur, Closure, TypeScript

Use Node.js

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

TypeScript

The JavaScript problem

No modules, only files

No linkage

No static checking

Hard to refactor

So Google created AtScript

The death of AtScriptGoogle 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?

Annotation

A declarative way to add metadata to code

Three types:

Type

Field

Metadata

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)); } }

Decorators

A proposed standard for ES2016

Created by Yehuda Katz (Ember)

Implemented in TypeScript

Implement Angular’s Annotation

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.jsonemitDecoratorMetadata: 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)

Other features

Class

Modules

Generics

Demo

Download the project quizzer-start from GitHub

https://github.com/Rockncoder/quizzer-start

From the root: npm start

Instructions

npm install -g typescript (gives us the tsc command)

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

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

Angular 2 main concepts

Module

Component

Template

Data binding

Metadata

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

Is a way to describe a view using HTML

Templates can be included with the component

Or as a URL link to an HTML file

Best practice is to use an HTML file

Data bindingComponent —— DOM

{{ value }} —> interpolation

[property] = “value” —> property binding (used to pass data from parent component to child)

(event) = “handler” <— event binding

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

Service

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

Used to share code across an app

Lazily instantiated

Angular has no “Service” defined type

DirectivesA 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

A component is a directive with a view

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 'angular2/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 injectionA 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?

A. Nothing, they are the same thing.

B. A component is a directive with a view.

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

D. All of the above.

Lifecycle Hooks

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

RxJS

Reactive Extensions (Rx)

Rx = Observables + LINQ + Schedulers

An API for asynchronous stream programming

The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators.

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

describe

Used to group tests together

Takes two params: a string and a callback

Can be nested

it

Used when we want to create a specific test

Takes two params: a string and a callback

expect

The actual test

Contains a Matcher (toBe, toThrow, toBeNull, and more)

URLs

https://angular.io/

https://material.angular.io/

https://github.com/systemjs/systemjs

Summary

Angular 2 is simpler than AngularJS

You should know JavaScript well

TypeScript is the preferred language for Angular 2

The framework is made to be easily testable