Download - Angular 2 Weekend Workshop
Angular 2.0 Weekend WorkshopCowork South Bay 22 + 23 Oct 2016
Troy MilesTroy Miles
Speaker and author
https://therockncoder.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
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
More URLshttp://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
Links
Slides: http://www.slideshare.net/rockncoder/angular-2-weekend-workshop
Code: https://github.com/Rockncoder/quizzer-start
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