├── 10 ├── app.ts ├── components │ ├── card.ts │ ├── home.ts │ ├── party.ts │ └── person-list.ts ├── favicon.ico ├── index.html ├── main.ts ├── pipes │ └── search.ts └── services │ └── starwars.ts ├── 11 ├── app.ts ├── components │ ├── card.ts │ ├── home.ts │ ├── party.ts │ └── person-list.ts ├── favicon.ico ├── index.html ├── main.ts ├── pipes │ └── search.ts └── services │ ├── party.ts │ └── starwars.ts ├── .editorconfig ├── .gitignore ├── 01 ├── app.ts ├── favicon.ico ├── index.html └── main.ts ├── 02 ├── app.ts ├── components │ └── home.ts ├── favicon.ico ├── index.html └── main.ts ├── 03 ├── app.ts ├── components │ └── home.ts ├── favicon.ico ├── index.html └── main.ts ├── 04 ├── app.ts ├── components │ ├── home.ts │ └── person-list.ts ├── favicon.ico ├── index.html └── main.ts ├── 05 ├── app.ts ├── components │ ├── home.ts │ └── person-list.ts ├── favicon.ico ├── index.html └── main.ts ├── 06 ├── app.ts ├── components │ ├── card.ts │ ├── home.ts │ └── person-list.ts ├── favicon.ico ├── index.html └── main.ts ├── 07 ├── app.ts ├── components │ ├── card.ts │ ├── home.ts │ └── person-list.ts ├── favicon.ico ├── index.html ├── main.ts └── services │ └── starwars.ts ├── 08 ├── app.ts ├── components │ ├── card.ts │ ├── home.ts │ └── person-list.ts ├── favicon.ico ├── index.html ├── main.ts └── services │ └── starwars.ts ├── 09 ├── app.ts ├── components │ ├── card.ts │ ├── home.ts │ └── person-list.ts ├── favicon.ico ├── index.html ├── main.ts ├── pipes │ └── search.ts └── services │ └── starwars.ts ├── LICENSE ├── README.md ├── package.json ├── src ├── app.ts ├── favicon.ico ├── index.html └── main.ts ├── tsconfig.json ├── typings.json └── webpack.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | charset = utf-8 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | insert_final_newline = true 11 | trim_trailing_whitespace = true 12 | 13 | [*.md] 14 | insert_final_newline = false 15 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | /node_modules/ 3 | /dist/ 4 | /npm-debug.log 5 | /typings/ 6 | .DS_Store 7 | -------------------------------------------------------------------------------- /01/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app', 5 | template: `
6 | 7 | Hello World! 8 | 9 |
10 | ` 11 | }) 12 | export class App{} 13 | -------------------------------------------------------------------------------- /01/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/01/favicon.ico -------------------------------------------------------------------------------- /01/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /01/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /02/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | @Component({ 4 | selector: 'app', 5 | directives: [Home], 6 | template: `
7 | 8 | Hello World! 9 | 10 | 11 | 12 |
13 | ` 14 | }) 15 | export class App{} 16 | -------------------------------------------------------------------------------- /02/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'home', 5 | template: ` 6 | 7 | I'm the home template 8 | 9 | ` 10 | }) 11 | export class Home{} 12 | -------------------------------------------------------------------------------- /02/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/02/favicon.ico -------------------------------------------------------------------------------- /02/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /02/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /03/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | @Component({ 4 | selector: 'app', 5 | directives: [Home], 6 | template: `
7 | 8 | Hello World! 9 | 10 | 11 | 12 |
13 | ` 14 | }) 15 | export class App{} 16 | -------------------------------------------------------------------------------- /03/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'home', 5 | template: ` 6 | 7 | I'm the home template 8 | 9 | 10 |
11 | 12 | 13 | 14 | ` 15 | }) 16 | export class Home{ 17 | onClick(input){ 18 | console.log(input); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /03/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/03/favicon.ico -------------------------------------------------------------------------------- /03/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /03/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /04/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | @Component({ 4 | selector: 'app', 5 | directives: [Home], 6 | template: `
7 | 8 | Hello World! 9 | 10 | 11 | 12 |
13 | ` 14 | }) 15 | export class App{} 16 | -------------------------------------------------------------------------------- /04/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | 4 | @Component({ 5 | selector: 'home', 6 | directives: [PersonList], 7 | template: ` 8 | 9 | I'm the home template 10 | 11 | 12 |
13 | 14 | 15 | ` 16 | }) 17 | export class Home{ 18 | people = [{name:"John"}]; 19 | 20 | onSelect(person){ 21 | console.log(person); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /04/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'person-list', 5 | template: ` 6 | 7 | 8 |
9 | {{people[0].name}} 10 |
11 | ` 12 | }) 13 | export class PersonList{ 14 | @Input() people; 15 | @Output() select = new EventEmitter(); 16 | 17 | onClick(value){ 18 | this.select.emit(value); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /04/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/04/favicon.ico -------------------------------------------------------------------------------- /04/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /04/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /05/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | @Component({ 4 | selector: 'app', 5 | directives: [Home], 6 | template: ` 7 | 8 | Hello World! 9 | 10 | 11 | 12 | ` 13 | }) 14 | export class App{} 15 | -------------------------------------------------------------------------------- /05/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | 4 | @Component({ 5 | selector: 'home', 6 | directives: [PersonList], 7 | template: ` 8 | 9 | I'm the home template 10 | 11 | 12 |
13 | 14 | 15 | ` 16 | }) 17 | export class Home{ 18 | people = [{name:"John"}]; 19 | 20 | onSelect(person){ 21 | console.log(person); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /05/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'person-list', 5 | template: ` 6 | 9 | 10 | 11 | 12 | 13 |
14 | 19 | {{name}} 20 | 24 | 25 | 26 | 27 |
28 | {{people[0].name}} 29 |
30 | ` 31 | }) 32 | export class PersonList{ 33 | @Input() people; 34 | @Output() select = new EventEmitter(); 35 | 36 | onClick(value){ 37 | this.select.emit(value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /05/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/05/favicon.ico -------------------------------------------------------------------------------- /05/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /05/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /06/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | @Component({ 4 | selector: 'app', 5 | directives: [Home], 6 | template: `
7 | 8 | Hello World! 9 | 10 | 11 | 12 |
13 | ` 14 | }) 15 | export class App{} 16 | -------------------------------------------------------------------------------- /06/components/card.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | @Component({ 3 | selector: 'card', 4 | template: ` 19 |
20 | 21 |
22 |
{{person.name}}
23 | Add to Party 24 |
25 |
26 | ` 27 | }) 28 | export class Card{ 29 | @Input() person; 30 | } 31 | -------------------------------------------------------------------------------- /06/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | 4 | @Component({ 5 | selector: 'home', 6 | directives: [PersonList], 7 | template: ` 8 | 9 | I'm the home template 10 | 11 | 12 |
13 | 14 | 15 | ` 16 | }) 17 | export class Home{ 18 | people = [ 19 | { 20 | name:"Luke Skywalker", 21 | image: "http://localhost:4000/luke_skywalker.jpg" 22 | }, 23 | { 24 | name:"Darth Vader", 25 | image: "http://localhost:4000/darth_vader.jpg" 26 | }, 27 | { 28 | name:"Leia Organa", 29 | image: "http://localhost:4000/leia_organa.jpg" 30 | } 31 | ]; 32 | 33 | onSelect(person){ 34 | console.log(person); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /06/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | import {Card} from './card'; 3 | 4 | @Component({ 5 | selector: 'person-list', 6 | directives: [Card], 7 | template: ` 19 | 20 | 21 | 22 | 23 |
24 | 29 | {{name}} 30 | 34 | 35 | 36 |
37 | 40 | 41 |
42 | ` 43 | }) 44 | export class PersonList{ 45 | @Input() people; 46 | @Output() select = new EventEmitter(); 47 | 48 | onClick(value){ 49 | this.select.emit(value); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /06/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/06/favicon.ico -------------------------------------------------------------------------------- /06/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /06/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /07/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | @Component({ 4 | selector: 'app', 5 | directives: [Home], 6 | template: `
7 | 8 | Hello World! 9 | 10 | 11 | 12 |
13 | ` 14 | }) 15 | export class App{} 16 | -------------------------------------------------------------------------------- /07/components/card.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | @Component({ 3 | selector: 'card', 4 | template: ` 19 |
20 | 21 |
22 |
{{person.name}}
23 | Add to Party 24 |
25 |
26 | ` 27 | }) 28 | export class Card{ 29 | @Input() person; 30 | } 31 | -------------------------------------------------------------------------------- /07/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | import {StarWars} from '../services/starwars'; 4 | 5 | @Component({ 6 | selector: 'home', 7 | directives: [PersonList], 8 | providers: [StarWars], 9 | template: ` 10 | 11 | I'm the home template 12 | 13 | 14 |
15 | 16 | 17 | ` 18 | }) 19 | export class Home{ 20 | 21 | constructor(public starWars:StarWars){} 22 | 23 | onSelect(person){ 24 | console.log(person); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /07/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | import {Card} from './card'; 3 | 4 | @Component({ 5 | selector: 'person-list', 6 | directives: [Card], 7 | template: ` 18 | 19 | 20 | 21 | 22 |
23 | 28 | {{name}} 29 | 33 | 34 | 35 |
36 | 39 | 40 |
41 | ` 42 | }) 43 | export class PersonList{ 44 | @Input() people; 45 | @Output() select = new EventEmitter(); 46 | 47 | onClick(value){ 48 | this.select.emit(value); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /07/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/07/favicon.ico -------------------------------------------------------------------------------- /07/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /07/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /07/services/starwars.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | @Injectable() 3 | export class StarWars{ 4 | people = [ 5 | { 6 | name:"Luke Skywalker", 7 | image: "http://localhost:4000/luke_skywalker.jpg" 8 | }, 9 | { 10 | name:"Darth Vader", 11 | image: "http://localhost:4000/darth_vader.jpg" 12 | }, 13 | { 14 | name:"Leia Organa", 15 | image: "http://localhost:4000/leia_organa.jpg" 16 | } 17 | ]; 18 | } 19 | -------------------------------------------------------------------------------- /08/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | import {HTTP_PROVIDERS} from '@angular/http'; 4 | @Component({ 5 | selector: 'app', 6 | directives: [Home], 7 | providers: [HTTP_PROVIDERS], 8 | template: `
9 | 10 | Hello World! 11 | 12 | 13 | 14 |
15 | ` 16 | }) 17 | export class App{} 18 | -------------------------------------------------------------------------------- /08/components/card.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | @Component({ 3 | selector: 'card', 4 | template: ` 19 |
20 | 21 |
22 |
{{person.name}}
23 | Add to Party 24 |
25 |
26 | ` 27 | }) 28 | export class Card{ 29 | @Input() person; 30 | } 31 | -------------------------------------------------------------------------------- /08/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | import {StarWars} from '../services/starwars'; 4 | 5 | @Component({ 6 | selector: 'home', 7 | directives: [PersonList], 8 | providers: [StarWars], 9 | template: ` 10 | 11 | I'm the home template 12 | 13 | 14 |
15 | 16 | 17 | ` 18 | }) 19 | export class Home{ 20 | 21 | constructor(public starWars:StarWars){} 22 | 23 | onSelect(person){ 24 | console.log(person); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /08/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | import {Card} from './card'; 3 | 4 | @Component({ 5 | selector: 'person-list', 6 | directives: [Card], 7 | template: ` 18 | 19 | 20 | 21 | 22 |
23 | 28 | {{name}} 29 | 33 | 34 | 35 |
36 | 39 | 40 |
41 | ` 42 | }) 43 | export class PersonList{ 44 | @Input() people; 45 | @Output() select = new EventEmitter(); 46 | 47 | onClick(value){ 48 | this.select.emit(value); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /08/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/08/favicon.ico -------------------------------------------------------------------------------- /08/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /08/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /08/services/starwars.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Http} from '@angular/http'; 3 | import 'rxjs/add/operator/map'; 4 | 5 | const API = 'http://localhost:4000'; 6 | 7 | @Injectable() 8 | export class StarWars{ 9 | people; 10 | constructor(private _http:Http){ 11 | this.people = _http.get(`${API}/people`) 12 | .map(res => res.json() //get the response as json 13 | .map(person => 14 | Object.assign(person, {image: `${API}/${person.image}`}) 15 | ) 16 | ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /09/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | import {HTTP_PROVIDERS} from '@angular/http'; 4 | @Component({ 5 | selector: 'app', 6 | directives: [Home], 7 | providers: [HTTP_PROVIDERS], 8 | template: `
9 | 10 |
11 | ` 12 | }) 13 | export class App{} 14 | -------------------------------------------------------------------------------- /09/components/card.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | @Component({ 3 | selector: 'card', 4 | template: ` 22 |
23 | 24 |
25 |
{{person.name}}
26 | Add to Party 27 |
28 |
29 | ` 30 | }) 31 | export class Card{ 32 | @Input() person; 33 | } 34 | -------------------------------------------------------------------------------- /09/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | import {StarWars} from '../services/starwars'; 4 | 5 | @Component({ 6 | selector: 'home', 7 | directives: [PersonList], 8 | providers: [StarWars], 9 | template: ` 10 | 14 | 15 | ` 16 | }) 17 | export class Home{ 18 | 19 | constructor(public starWars:StarWars){} 20 | 21 | onSelect(person){ 22 | console.log(person); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /09/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | import {Card} from './card'; 3 | 4 | @Component({ 5 | selector: 'person-list', 6 | directives: [Card], 7 | template: ` 18 | 19 | 20 | 21 | 22 |
23 | 28 | {{name}} 29 | 33 | 34 | 35 |
36 | 39 | 40 |
41 | ` 42 | }) 43 | export class PersonList{ 44 | @Input() people; 45 | @Output() select = new EventEmitter(); 46 | 47 | onClick(value){ 48 | this.select.emit(value); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /09/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/09/favicon.ico -------------------------------------------------------------------------------- /09/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | Loading... 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /09/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /09/pipes/search.ts: -------------------------------------------------------------------------------- 1 | import {Pipe} from '@angular/core'; 2 | @Pipe({ 3 | name: 'search' 4 | }) 5 | export class Search{ 6 | transform(data, key, term = ""){ 7 | if(!data) return null; 8 | return data.filter(item => { 9 | return item[key].toLowerCase().includes(term.toLowerCase()); 10 | }) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /09/services/starwars.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Http} from '@angular/http'; 3 | import 'rxjs/add/operator/map'; 4 | 5 | const API = 'http://localhost:4000'; 6 | 7 | @Injectable() 8 | export class StarWars{ 9 | people; 10 | constructor(private _http:Http){ 11 | this.people = _http.get(`${API}/people`) 12 | .map(res => res.json() //get the response as json 13 | .map(person => 14 | Object.assign(person, {image: `${API}/${person.image}`}) 15 | ) 16 | ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /10/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | import {HTTP_PROVIDERS} from '@angular/http'; 4 | import {ROUTER_PROVIDERS, RouteConfig, RouterOutlet, RouterLink} from '@angular/router-deprecated'; 5 | import {Party} from './components/party'; 6 | 7 | @Component({ 8 | selector: 'app', 9 | directives: [RouterOutlet, RouterLink], 10 | providers: [HTTP_PROVIDERS, ROUTER_PROVIDERS], 11 | template: ` 18 |
19 | 27 | 28 |
29 | ` 30 | }) 31 | @RouteConfig([ 32 | {path: '/home', name: 'Home', component: Home, useAsDefault: true}, 33 | {path: '/party', name: 'Party', component: Party}, 34 | {path: '/**', redirectTo: ['Home'] } 35 | ]) 36 | export class App { 37 | } 38 | -------------------------------------------------------------------------------- /10/components/card.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input} from '@angular/core'; 2 | @Component({ 3 | selector: 'card', 4 | template: ` 19 |
20 | 21 |
22 |
{{person.name}}
23 | Add to Party 24 |
25 |
26 | ` 27 | }) 28 | export class Card{ 29 | @Input() person; 30 | } 31 | -------------------------------------------------------------------------------- /10/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | import {StarWars} from '../services/starwars'; 4 | 5 | @Component({ 6 | selector: 'home', 7 | directives: [PersonList], 8 | providers: [StarWars], 9 | template: ` 10 | 14 | 15 | ` 16 | }) 17 | export class Home{ 18 | 19 | constructor(public starWars:StarWars){} 20 | 21 | onSelect(person){ 22 | console.log(person); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /10/components/party.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'party', 5 | template: ` 6 | It's a party! 7 | ` 8 | }) 9 | export class Party{} 10 | -------------------------------------------------------------------------------- /10/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | import {Card} from './card'; 3 | import {Search} from '../pipes/search'; 4 | 5 | @Component({ 6 | selector: 'person-list', 7 | directives: [Card], 8 | pipes:[Search], 9 | template: ` 20 | 21 | 22 | 23 |
24 | 27 | 28 |
29 | ` 30 | }) 31 | export class PersonList{ 32 | @Input() people; 33 | @Output() select = new EventEmitter(); 34 | 35 | onClick(value){ 36 | this.select.emit(value); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /10/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/10/favicon.ico -------------------------------------------------------------------------------- /10/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | 11 | Loading... 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /10/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /10/pipes/search.ts: -------------------------------------------------------------------------------- 1 | import {Pipe} from '@angular/core'; 2 | @Pipe({ 3 | name: 'search' 4 | }) 5 | export class Search{ 6 | transform(data, key, term = ""){ 7 | if(!data) return null; 8 | return data.filter(item => { 9 | return item[key].toLowerCase().includes(term.toLowerCase()); 10 | }) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /10/services/starwars.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Http} from '@angular/http'; 3 | import 'rxjs/add/operator/map'; 4 | 5 | const API = 'http://localhost:4000'; 6 | 7 | @Injectable() 8 | export class StarWars{ 9 | people; 10 | constructor(private _http:Http){ 11 | this.people = _http.get(`${API}/people`) 12 | .map(res => res.json() //get the response as json 13 | .map(person => 14 | Object.assign(person, {image: `${API}/${person.image}`}) 15 | ) 16 | ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /11/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {Home} from './components/home'; 3 | import {HTTP_PROVIDERS} from '@angular/http'; 4 | import {ROUTER_PROVIDERS, RouteConfig, RouterOutlet, RouterLink} from '@angular/router-deprecated'; 5 | import {Party} from './components/party'; 6 | import {PartyService} from './services/party'; 7 | 8 | @Component({ 9 | selector: 'app', 10 | directives: [RouterOutlet, RouterLink], 11 | providers: [HTTP_PROVIDERS, ROUTER_PROVIDERS, PartyService], 12 | template: ` 19 | 20 |
21 | 29 | 30 |
31 | ` 32 | }) 33 | @RouteConfig([ 34 | {path: '/home', name: 'Home', component: Home, useAsDefault: true}, 35 | {path: '/party', name: 'Party', component: Party}, 36 | {path: '/**', redirectTo: ['Home'] } 37 | ]) 38 | export class App { 39 | constructor(public party:PartyService){} 40 | } 41 | -------------------------------------------------------------------------------- /11/components/card.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, EventEmitter, Output} from '@angular/core'; 2 | @Component({ 3 | selector: 'card', 4 | template: ` 19 |
20 | 21 |
22 |
{{person.name}}
23 | Add to Party 24 |
25 |
26 | ` 27 | }) 28 | export class Card{ 29 | @Input() person; 30 | @Output() add = new EventEmitter(); 31 | } 32 | -------------------------------------------------------------------------------- /11/components/home.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PersonList} from './person-list'; 3 | import {StarWars} from '../services/starwars'; 4 | import {PartyService} from '../services/party'; 5 | import {Party} from './party'; 6 | import {RouteConfig, RouterOutlet} from '@angular/router-deprecated'; 7 | 8 | @Component({ 9 | selector: 'home', 10 | directives: [PersonList, RouterOutlet], 11 | providers: [StarWars], 12 | template: ` 13 | 17 | 18 | ` 19 | }) 20 | export class Home{ 21 | 22 | constructor(public starWars:StarWars, public party:PartyService){} 23 | 24 | onSelect(person){ 25 | console.log('onSelect'); 26 | this.party.addAttendee(person); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /11/components/party.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | import {PartyService} from '../services/party'; 3 | 4 | @Component({ 5 | selector: 'party', 6 | template: ` 11 | ` 12 | }) 13 | export class Party { 14 | constructor(public partyService:PartyService) { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /11/components/person-list.ts: -------------------------------------------------------------------------------- 1 | import {Component, Input, Output, EventEmitter} from '@angular/core'; 2 | import {Card} from './card'; 3 | import {Search} from '../pipes/search'; 4 | 5 | @Component({ 6 | selector: 'person-list', 7 | directives: [Card], 8 | pipes:[Search], 9 | template: ` 20 | 21 | 22 | 23 |
24 | 29 | 30 |
31 | ` 32 | }) 33 | export class PersonList{ 34 | @Input() people; 35 | @Output() select = new EventEmitter(); 36 | } 37 | -------------------------------------------------------------------------------- /11/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/11/favicon.ico -------------------------------------------------------------------------------- /11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | 11 | Loading... 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /11/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'zone.js/dist/zone'; 3 | 4 | import 'bootstrap/dist/css/bootstrap.css'; 5 | import 'font-awesome/css/font-awesome.css'; 6 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 7 | 8 | import {bootstrap} from '@angular/platform-browser-dynamic'; 9 | import {App} from './app'; 10 | 11 | bootstrap(App) 12 | .then(()=> console.log(`App Running...`)) 13 | .catch(err => console.log(err)); 14 | -------------------------------------------------------------------------------- /11/pipes/search.ts: -------------------------------------------------------------------------------- 1 | import {Pipe} from '@angular/core'; 2 | @Pipe({ 3 | name: 'search' 4 | }) 5 | export class Search{ 6 | transform(data, key, term = ""){ 7 | if(!data) return null; 8 | return data.filter(item => { 9 | return item[key].toLowerCase().includes(term.toLowerCase()); 10 | }) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /11/services/party.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | 3 | @Injectable() 4 | export class PartyService{ 5 | public attendees = []; 6 | 7 | get total(){ 8 | return this.attendees.length; 9 | } 10 | 11 | addAttendee(person){ 12 | this.attendees = [...this.attendees, person]; 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /11/services/starwars.ts: -------------------------------------------------------------------------------- 1 | import {Injectable} from '@angular/core'; 2 | import {Http} from '@angular/http'; 3 | import 'rxjs/add/operator/map'; 4 | 5 | const API = 'http://localhost:4000'; 6 | 7 | @Injectable() 8 | export class StarWars{ 9 | people; 10 | constructor(private _http:Http){ 11 | this.people = _http.get(`${API}/people`) 12 | .map(res => res.json() //get the response as json 13 | .map(person => 14 | Object.assign(person, {image: `${API}/${person.image}`}) 15 | ) 16 | ) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | {% raw %} 2 | 3 | ## Angular 2 StarWars Party 4 | 5 | ### Workshop Resources 6 | - [Angular 2 Cheat Sheet](https://angular.io/docs/ts/latest/cheatsheet.html) 7 | - [Bootstrap 4 Cheat Sheet](http://hackerthemes.com/bootstrap-cheatsheet/) 8 | - [Font Awesome Cheat Sheet](https://fortawesome.github.io/Font-Awesome/icons/) 9 | 10 | ### Completed Exercises 11 | The numbers folders 01-10 can be renamed at any time to catch up. 12 | For example, rename `07` to `src` then restart your `npm start` to catch up to Exercise 7. 13 | 14 | ### Exercise 00 - Setup 15 | - Clone or fork this repository 16 | - Make sure you have [node.js](https://nodejs.org/) installed 17 | - Run `npm install -g webpack webpack-dev-server typings typescript` to install global dependencies 18 | - Navigate to your project folder from the command line 19 | - Run `npm install` to install dependencies 20 | - Run `npm start` to fire up dev server 21 | - Open browser to [`http://localhost:3000`](http://localhost:3000) 22 | 23 | #### Set up the StarWars server 24 | - Install and run [https://github.com/johnlindquist/swapi-json-server](https://github.com/johnlindquist/swapi-json-server) 25 | - Open browser to [`http://localhost:4000`](http://localhost:4000) 26 | 27 | ### Exercise 01 - Hello World 28 | - Notice the `` tag in `index.html` 29 | - Delete everything in `app.ts` 30 | - Write a `@Component` with a selector of `'app'` 31 | - Create a basic `template` 32 | - Remember to `export` your `class` 33 | 34 | ### Exercise 02 - Create a Component 35 | - Create a `components` directory 36 | - Add a file called `home.ts` 37 | - Create a `@Component` and `export` it 38 | - Import your component into `app.ts` 39 | - Include the component with `directives:[Home]` 40 | - Add the component to your `template` with `` 41 | 42 | ### Exercise 03 - Handling Clicks and Refs 43 | #### Logging an event 44 | - Create a button in your `Home` component 45 | - Handle the click with a `(click)="onClick($event)"` 46 | - Log out the event 47 | 48 | #### Logging an Input 49 | - Create an `input` 50 | - Reference the `input` with a `#i` 51 | - Pass the value with `#i.value` of the input to the `onClick` 52 | - Log out the value 53 | 54 | ### Exercise 04 - Smart and Dumb Components 55 | #### Inputs 56 | - Add a `people = [{name:"John"}];` to your `Home` component 57 | - Create a `PersonList` component 58 | - Add the `PersonList` to your `Home` component 59 | - Create an `@Input` called `people` (remember to import it) 60 | - Push `people` from `Home` into `PersonList` with `[people]=people` 61 | - Render the first person from the `@Input` with `{{people[0].name}}` 62 | 63 | #### Outputs 64 | - Move the `input` and the `button` to the `PersonList` 65 | - Create an `@Output()` called `select` 66 | - Call `select.emit(value)` in the button's `onClick` handler 67 | - Handle the `select` event in`Home` with `(select)=onSelect($event)` 68 | - Log out the input 69 | 70 | ### Exercise 05 - Templates, Styles, and Built-in Directives 71 | #### `NgModel` 72 | - Add an `[(ngModel)]="name"` to the `input` 73 | - Add a `{{name}}` 74 | - Type in the `input` to see the name appear in the `` 75 | 76 | #### `` tag to the template 78 | - Add a `.person { cursor: pointer; cursor: hand; }` style 79 | - Add the `class=person` to your span 80 | - Roll over your `` to see the hand cursor 81 | 82 | #### `*ngIf` 83 | - Add a `` 84 | - Add an `*ngIf="name"` to the `` 85 | - Type in the input to see the `` appear 86 | 87 | #### `[ngClass]` 88 | - Add `(mouseover)="isOver = true" (mouseout)="isOver = false"` to `span` 89 | - Change the `class` attribute to `class="fa"` on the `` element 90 | - Add `[ngClass]="{'fa-star':isOver, 'fa-star-o':!isOver}"` to the `` 91 | - Roll over the span to see the icon toggle 92 | 93 | ### Exercise 06 - Repeating Elements with *ngFor 94 | 95 | #### `*ngFor` 96 | - Add more `people` to the `Home` 97 | ```js 98 | people = [ 99 | { 100 | name:"Luke Skywalker", 101 | image: "http://localhost:4000/luke_skywalker.jpg" 102 | }, 103 | { 104 | name:"Darth Vader", 105 | image: "http://localhost:4000/darth_vader.jpg" 106 | }, 107 | { 108 | name:"Leia Organa", 109 | image: "http://localhost:4000/leia_organa.jpg" 110 | } 111 | ]; 112 | ``` 113 | #### Loop through each person using `*ngFor` on a simple element 114 | - Create a `p` element in `PersonList` that binds to `person.name` 115 | - Add `*ngFor="let person of people"` to the `p` tag 116 | 117 | #### Loop through each person using `*ngFor` on a custom component 118 | - Create a `Card` component using the code below as a reference 119 | - Give the `Card` an `@Input()` of `person` 120 | - Add the `Card` to the `PersonList` 121 | - Add `*ngFor="let person of people"` to the `card` 122 | - Update the `src` to `[src]="person.image"` 123 | - Show the `person.name` in the `h5` with `{{person.name}}` 124 | 125 | ```js 126 | 127 | import {Component, Input} from '@angular/core'; 128 | @Component({ 129 | selector: 'card', 130 | template: ` 145 |
146 | 147 |
148 |
{{person.name}}
149 | Add to Party 150 |
151 |
152 | ` 153 | }) 154 | export class Card{ 155 | @Input() person; 156 | } 157 | 158 | ``` 159 | 160 | ### Exercise 07 - Move the Data to a Service 161 | - Create `services` directory 162 | - Create a `StarWars.ts` file 163 | - Use the `@Inject()` decorator on a `StarWars` class 164 | - Move the `people` from the `Home` to the service 165 | - Include the service in the `Home` `providers:[]` 166 | - Inject the service `constructor(public starWars:StarWars){}` 167 | - Use the service in the template `[people]="starWars.people"` 168 | 169 | 170 | ### Exercise 08 - Loading Data with Http 171 | - Add `providers: [HTTP_PROVIDERS],` to your `app.ts` 172 | - Import `import {Http} from '@angular/http';` in your service 173 | - Inject `Http` in your service `constructor(private _http:Http){}` 174 | - Delete the `people` array 175 | - In the constructor, assign the people to an `http` request 176 | - Use `http.get()` then `map` then response using `res => res.json()` 177 | - `map` the images: `luke_skywalker.jpg` to `http://locahost:4000/luke_skywalker.jpg` 178 | 179 | ```js 180 | import {Injectable} from '@angular/core'; 181 | import {Http} from '@angular/http'; 182 | import 'rxjs/add/operator/map'; 183 | 184 | const API = 'http://localhost:4000'; 185 | 186 | @Injectable() 187 | export class StarWars{ 188 | people; 189 | constructor(private _http:Http){ 190 | this.people = _http.get(`${API}/people`) 191 | .map(res => res.json() //get the response as json 192 | .map(person => 193 | Object.assign(person, {image: `${API}/${person.image}`}) 194 | ) 195 | ) 196 | } 197 | } 198 | 199 | ``` 200 | 201 | Use an `| async` pipe to load the data in the template 202 | ```js 203 | [people]="starWars.people | async" 204 | ``` 205 | 206 | ### Exercise 09 - Searching Data with a Pipe 207 | #### Housekeeping 208 | - Clean up `PersonList` template so only `input` and `card`s remain 209 | 210 | ```js 211 | 212 | 213 |
214 | 217 | 218 |
219 | ``` 220 | 221 | #### Creating a Pipe 222 | - Create a `pipes` directory 223 | - Create a `search.ts` file 224 | - Create a `@Pipe()` called `Search` 225 | - Create your own searching logic 226 | ```js 227 | import {Pipe} from '@angular/core'; 228 | @Pipe({ 229 | name: 'search' 230 | }) 231 | export class Search{ 232 | transform(data, key, term = ""){ 233 | if(!data) return null; 234 | return data.filter(item => { 235 | return item[key] 236 | .toLowerCase() 237 | .includes(term.toLowerCase()); 238 | }) 239 | } 240 | } 241 | ``` 242 | 243 | #### Using the Pipe 244 | Add the `Search` to your `PersonList` 245 | ```js 246 | pipes:[Search], 247 | ``` 248 | 249 | - Add the `name` ("search") of the `Search` pipe to the template 250 | - Use `'name'` as the `key` to search on 251 | - Use the `name` from the `[(ngModel)]="name"` as the term 252 | ```js 253 | let person of people | search:'name':name" 254 | ``` 255 | 256 | 257 | ### Exercise 10 - Adding Routes 258 | - Add a `` to your `index.html` `` 259 | - Create a simple `Party` component with a `hello world` template 260 | - Import all the required Router classes into `app.ts` 261 | ```js 262 | import {ROUTER_PROVIDERS, RouteConfig, RouterOutlet, RouterLink} from '@angular/router'; 263 | ``` 264 | - Include `RouterOutlet` and `RouterLink` in your `directives:[]` 265 | ```js 266 | directives: [RouterOutlet, RouterLink], 267 | ``` 268 | - Replace `` the `` 269 | - Decorate your `App` with your routes 270 | ```js 271 | @RouteConfig([ 272 | {path: '/home', name: 'Home', component: Home, useAsDefault: true}, 273 | {path: '/party', name: 'Party', component: Party}, 274 | {path: '/**', redirectTo: ['Home'] } 275 | ]) 276 | ``` 277 | - Create a nav with `[routerLink]` 278 | ```js 279 | 287 | ``` 288 | - Stylize the active route with a `.router-link-active` style: 289 | ```css 290 | .router-link-active{ 291 | color: #55595c; 292 | background-color: #fff; 293 | border-color: #ddd #ddd transparent; 294 | } 295 | ``` 296 | 297 | ## Challenges (Solutions Not Included!) 298 | The following are for people who enjoy a challenge and working ahead. 299 | 300 | ### Challenge 301 | Create a second service with a route to manage who you "Add" to the Party. 302 | 303 | ### Moderate Challenge 304 | Add create, read, update, delete to the "Party" service 305 | so you can add, remove, edit people to the party. Also make 306 | sure you can't add the same Person to the party twice. 307 | 308 | ### Difficult Challenge 309 | Create a "PersonDetail" component and route so that when you 310 | click on the Person image, it navigates to a route displaying 311 | Person's detail *including* all the images of starships they've 312 | flown :wink: 313 | 314 | ### Difficult Challenge 315 | Build an "Autocomplete" search box from the Star Wars api. 316 | Prior RxJS knowledge is recommended. 317 | 318 | ### Super Duper Tough Challenge 319 | Build a full Create, Read, Update, Delete app (the api supports it!) 320 | with the people from Star Wars including all of the features above! 321 | {% endraw %} 322 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-workshop", 3 | "version": "1.0.0", 4 | "description": "Egghead.io - Angular 2 Workshop", 5 | "scripts": { 6 | "typings-install": "node node_modules/typings/dist/bin.js install", 7 | "postinstall": "npm run typings-install", 8 | "build": "node node_modules/webpack/bin/webpack.js --inline --colors --progress --display-error-details --display-cached", 9 | "watch": "npm run build -- --watch", 10 | "server": "node node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --colors --progress --display-error-details --display-cached --port 3000 --content-base src", 11 | "start": "npm run server" 12 | }, 13 | "contributors": [ 14 | "John Lindquist" 15 | ], 16 | "license": "MIT", 17 | "devDependencies": { 18 | "awesome-typescript-loader": "~0.16.2", 19 | "css-loader": "^0.23.1", 20 | "es6-promise": "3.0.2", 21 | "es6-shim": "0.35.0", 22 | "file-loader": "^0.8.5", 23 | "html-loader": "^0.4.3", 24 | "html-webpack-plugin": "^2.16.0", 25 | "reflect-metadata": "0.1.2", 26 | "source-map-loader": "^0.1.5", 27 | "style-loader": "^0.13.1", 28 | "typescript": "~1.8.9", 29 | "typings": "^0.7.9", 30 | "url-loader": "^0.5.7", 31 | "webpack": "^1.12.9", 32 | "webpack-dev-server": "^1.14.0", 33 | "webpack-merge": "^0.8.4" 34 | }, 35 | "dependencies": { 36 | "@angular/http": "2.0.0-rc.1", 37 | "@angular/common": "2.0.0-rc.1", 38 | "@angular/compiler": "2.0.0-rc.1", 39 | "@angular/core": "2.0.0-rc.1", 40 | "@angular/platform-browser": "2.0.0-rc.1", 41 | "@angular/platform-browser-dynamic": "2.0.0-rc.1", 42 | "@angular/router-deprecated": "2.0.0-rc.1", 43 | "rxjs": "5.0.0-beta.6", 44 | "bootstrap": "^4.0.0-alpha.2", 45 | "core-js": "^2.2.0", 46 | "font-awesome": "^4.6.1", 47 | "zone.js": "~0.6.12" 48 | }, 49 | "keywords": [ 50 | "angular2" 51 | ], 52 | "repository": { 53 | "type": "git", 54 | "url": "git+https://github.com/johnlindquist/angular2-workshop.git" 55 | }, 56 | "bugs": { 57 | "url": "https://github.com/johnlindquist/angular2-workshop/issues" 58 | }, 59 | "homepage": "https://github.com/johnlindquiist/angular2-workshop#readme" 60 | } 61 | -------------------------------------------------------------------------------- /src/app.ts: -------------------------------------------------------------------------------- 1 | import {Component} from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app', 5 | template:` 6 |
7 | 8 | Hello World! 9 | 10 |
11 | ` 12 | }) 13 | export class App { 14 | } 15 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/johnlindquist/angular2-workshop/93957b46cd9460c59e71bc5f4ac6df6f940da3fe/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Egghead.io - Angular 2 Workshop 6 | 7 | 8 | 9 | 10 | 11 | Loading... 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import 'core-js'; 2 | import 'reflect-metadata'; 3 | import 'zone.js/dist/zone'; 4 | import 'zone.js/dist/long-stack-trace-zone'; 5 | import 'bootstrap/dist/css/bootstrap.css'; 6 | import 'font-awesome/css/font-awesome.css'; 7 | import 'font-awesome/fonts/fontawesome-webfont.woff2'; 8 | 9 | import {bootstrap} from '@angular/platform-browser-dynamic'; 10 | import {App} from './app'; 11 | 12 | bootstrap(App) 13 | .then(()=> console.log(`App Running...`)) 14 | .catch(err => console.log(err)); 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "outDir": "dist", 6 | "rootDir": ".", 7 | "sourceMap": true, 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "moduleResolution": "node" 11 | }, 12 | "exclude": [ 13 | "typings/main.d.ts", 14 | "typings/main", 15 | "node_modules" 16 | ], 17 | "compileOnSave": false, 18 | "buildOnSave": false, 19 | "atom": { "rewriteTsconfig": false } 20 | } 21 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angular2-workshop", 3 | "version": false, 4 | "dependencies": {}, 5 | "ambientDependencies": { 6 | "es6-shim": "registry:dt/es6-shim#0.31.2+20160317120654" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | var path = require('path'); 4 | 5 | 6 | // Webpack Config 7 | var webpackConfig = { 8 | entry: { 9 | 'app': './src/main.ts' 10 | }, 11 | 12 | output: { 13 | path: './dist' 14 | }, 15 | 16 | plugins: [ 17 | new webpack.optimize.CommonsChunkPlugin({name: ['app'], minChunks: Infinity}), 18 | new HtmlWebpackPlugin({ 19 | filename: 'index.html', 20 | favicon: './src/favicon.ico', 21 | template: './src/index.html' 22 | }) 23 | ], 24 | 25 | module: { 26 | loaders: [ 27 | // .ts files for TypeScript 28 | {test: /\.ts$/, loader: 'awesome-typescript-loader'}, 29 | {test: /\.css$/, loader: 'style-loader!css-loader'}, 30 | {test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&minetype=application/font-woff"}, 31 | {test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader"}, 32 | {test: /\.html$/, loader: 'html-loader'} 33 | ] 34 | } 35 | }; 36 | 37 | 38 | // Our Webpack Defaults 39 | var defaultConfig = { 40 | devtool: 'cheap-module-source-map', 41 | cache: true, 42 | debug: true, 43 | output: { 44 | filename: '[name].bundle.js', 45 | sourceMapFilename: '[name].map', 46 | chunkFilename: '[id].chunk.js' 47 | }, 48 | 49 | module: { 50 | preLoaders: [ 51 | { 52 | test: /\.js$/, 53 | loader: 'source-map-loader', 54 | exclude: [ 55 | // these packages have problems with their sourcemaps 56 | path.join(__dirname, 'node_modules', 'rxjs'), 57 | path.join(__dirname, 'node_modules', '@angular-material'), 58 | ] 59 | } 60 | ], 61 | noParse: [ 62 | path.join(__dirname, 'node_modules', 'zone.js', 'dist'), 63 | path.join(__dirname, 'node_modules', '@angular', 'bundles') 64 | ] 65 | }, 66 | 67 | resolve: { 68 | root: [path.join(__dirname, 'src')], 69 | extensions: ['', '.ts', '.js'] 70 | }, 71 | 72 | devServer: { 73 | historyApiFallback: true, 74 | watchOptions: {aggregateTimeout: 300, poll: 1000} 75 | }, 76 | 77 | node: { 78 | global: 1, 79 | crypto: 'empty', 80 | module: 0, 81 | Buffer: 0, 82 | clearImmediate: 0, 83 | setImmediate: 0 84 | } 85 | }; 86 | 87 | var webpackMerge = require('webpack-merge'); 88 | module.exports = webpackMerge(defaultConfig, webpackConfig); 89 | --------------------------------------------------------------------------------