Skip to content

Commit

Permalink
Upgrade to Angular rc3, use Observables, replace in-memory api
Browse files Browse the repository at this point in the history
  • Loading branch information
smmorneau committed Jun 23, 2016
1 parent 72904d5 commit 1018c30
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 144 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## About
* Demo hosted on [Heroku](https://tour-of-heroes-typescript.herokuapp.com/)
(Using free dynos which sleep during inactivity, so initial load may be slow)
* Angular 2 Code in Typescript 1.8 with SystemJS for module loading
* Decouples components, models, services, and templates
* Typings will be used to manage type definitions until [Typescript 2.0]
Expand Down
2 changes: 1 addition & 1 deletion gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ gulp.task('bundle:js', function() {
return del(['public/dist/js/**/*', '!public/dist/js/app.min.js']);
})
.catch(function(err) {
console.error('>>> [systemjs-builder] Bundling failed'.bold.green);
console.error('>>> [systemjs-builder] Bundling failed'.bold.green, err);
});
});

Expand Down
19 changes: 9 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@
"test": "gulp test & live-server --open=tests/unit-tests.html --port=9999"
},
"dependencies": {
"@angular/common": "2.0.0-rc.1",
"@angular/compiler": "2.0.0-rc.1",
"@angular/core": "2.0.0-rc.1",
"@angular/http": "2.0.0-rc.1",
"@angular/platform-browser": "2.0.0-rc.1",
"@angular/platform-browser-dynamic": "2.0.0-rc.1",
"@angular/router": "2.0.0-rc.1",
"@angular/router-deprecated": "2.0.0-rc.1",
"@angular/upgrade": "2.0.0-rc.1",
"angular2-in-memory-web-api": "0.0.7",
"@angular/common": "2.0.0-rc.3",
"@angular/compiler": "2.0.0-rc.3",
"@angular/core": "2.0.0-rc.3",
"@angular/forms": "0.1.1",
"@angular/http": "2.0.0-rc.3",
"@angular/platform-browser": "2.0.0-rc.3",
"@angular/platform-browser-dynamic": "2.0.0-rc.3",
"@angular/router": "3.0.0-alpha.7",
"@angular/upgrade": "2.0.0-rc.3",
"bootstrap": "3.3.6",
"colors": "1.1.2",
"del": "2.2.0",
Expand Down
15 changes: 15 additions & 0 deletions server.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ app.set('port', (process.env.PORT || 8080));

app.use(express.static(__dirname + '/public'));

app.get('/app/heroes', function(req, res) {
res.json([
{id: 11, name: 'Mr. Nice'},
{id: 12, name: 'Narco'},
{id: 13, name: 'Bombasto'},
{id: 14, name: 'Celeritas'},
{id: 15, name: 'Magneta'},
{id: 16, name: 'RubberMan'},
{id: 17, name: 'Dynama'},
{id: 18, name: 'Dr IQ'},
{id: 19, name: 'Magma'},
{id: 20, name: 'Tornado'},
]);
});

app.get('*', function(req, res) {
res.sendFile(__dirname + '/src/html/index.html');
});
Expand Down
35 changes: 6 additions & 29 deletions src/js/components/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,25 @@
import { Component } from '@angular/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS } from '@angular/router-deprecated';
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';

import { DashboardComponent } from './dashboard.component';
import { HeroesComponent } from './heroes.component';
import { HeroDetailComponent } from './hero-detail.component';
import { HeroService } from '../services/hero.service';
import { HeroService } from '../services/hero.service';

@Component({
directives: [ROUTER_DIRECTIVES],
providers: [
ROUTER_PROVIDERS,
HeroService,
],
selector: 'my-app',
styleUrls: ['dist/css/component/app.component.css'],
template: `
<h1>{{title}}</h1>
<nav>
<a [routerLink]="['Dashboard']">Dashboard</a>
<a [routerLink]="['Heroes']">Heroes</a>
<!--<a [routerLink]="['/crisis-center']">Crisis Center</a>-->
<!--<a [routerLink]="['/dashboard']">Dashboard</a>-->
<a [routerLink]="['/heroes']">Heroes</a>
</nav>
<router-outlet></router-outlet>
`,
})

@RouteConfig([
{
component: DashboardComponent,
name: 'Dashboard',
path: '/dashboard',
useAsDefault: true,
},
{
component: HeroDetailComponent,
name: 'HeroDetail',
path: '/detail/:id',
},
{
component: HeroesComponent,
name: 'Heroes',
path: '/heroes',
},
])

export class AppComponent {
title = 'Tour of Heroes';
}
7 changes: 3 additions & 4 deletions src/js/components/dashboard.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router-deprecated';
import { Router } from '@angular/router';

import { Hero } from '../models/hero';
import { HeroService } from '../services/hero.service';
Expand All @@ -21,14 +21,13 @@ export class DashboardComponent implements OnInit {

getHeroes() {
this.heroService.getHeroes()
.then(heroes => {
.subscribe(heroes => {
this.heroes = heroes.slice(1, 5);
});
}

gotoDetail(hero: Hero) {
let link = ['HeroDetail', { id: hero.id }];
this.router.navigate(link);
this.router.navigate(['/detail/:id', { id: hero.id }]);
}

ngOnInit() {
Expand Down
62 changes: 35 additions & 27 deletions src/js/components/hero-detail.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { RouteParams } from '@angular/router-deprecated';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';

import { Hero } from '../models/hero';
import { HeroService } from '../services/hero.service';
Expand All @@ -11,43 +11,51 @@ import { htmlTemplate } from '../templates/hero-detail.html';
template: htmlTemplate,
})

export class HeroDetailComponent implements OnInit {
@Input() hero: Hero;
@Output() close = new EventEmitter();
export class HeroDetailComponent implements OnInit, OnDestroy {
hero: Hero;
error: any;
navigated = false; // true if navigated here
private sub: any;

constructor(
private _heroService: HeroService,
private _routeParams: RouteParams) {
private heroService: HeroService,
private route: ActivatedRoute,
private router: Router) {
}

ngOnInit() {
if (this._routeParams.get('id') !== null) {
let id = +this._routeParams.get('id');
this.navigated = true;
this._heroService.getHero(id)
.then(hero => this.hero = hero);
} else {
this.navigated = false;
this.hero = new Hero();
}
this.sub = this.route.params
.subscribe((params: any) => {
let id = +params.id; // (+) converts string 'id' to a number
if (id) {
this.heroService.getHero(id)
.subscribe(hero => this.hero = hero);
} else {
this.hero = new Hero();
}
});
}

ngOnDestroy() {
this.sub.unsubscribe();
}

save() {
this._heroService
this.heroService
.save(this.hero)
.then(hero => {
this.hero = hero; // saved hero, w/ id if new
this.goBack(hero);
})
.catch(error => this.error = error); // TODO: Display error message
.subscribe(
hero => {
this.hero = hero; // saved hero, w/ id if new
this.gotoHeroes();
},
error => this.error = error // TODO: Display error message
);
}

goBack(savedHero: Hero = null) {
this.close.emit(savedHero);
// TODO: use the routerCanDeactivate hook
if (this.navigated) { window.history.back(); }
gotoHeroes() {
let heroId = this.hero ? this.hero.id : null;
// Pass along the hero id if available
// so that the HeroList component can select that hero.
this.router.navigate(['/heroes'], { queryParams: { id: heroId } });
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router-deprecated';
import { Router } from '@angular/router';

import { Hero } from '../models/hero';
import { HeroDetailComponent } from './hero-detail.component';
Expand All @@ -13,21 +13,23 @@ import { htmlTemplate } from '../templates/heroes.html';
template: htmlTemplate,
})

export class HeroesComponent implements OnInit {
export class HeroesListComponent implements OnInit {
heroes: Hero[];
selectedHero: Hero;
addingHero = false;
error: any;

constructor(
private _router: Router,
private _heroService: HeroService) { }
private router: Router,
private heroService: HeroService) { }

getHeroes() {
this._heroService
this.heroService
.getHeroes()
.then(heroes => this.heroes = heroes)
.catch(error => this.error = error); // TODO: Display error message
.subscribe(
heroes => this.heroes = heroes,
error => this.error = error // TODO: Display error message
);
}

addHero() {
Expand All @@ -42,12 +44,12 @@ export class HeroesComponent implements OnInit {

delete(hero: Hero, event: any) {
event.stopPropagation();
this._heroService
this.heroService
.delete(hero)
.then(res => {
this.heroes = this.heroes.filter(h => h.id !== hero.id);
})
.catch(error => this.error = error); // TODO: Display error message
.subscribe(
res => this.heroes = this.heroes.filter(h => h.id !== hero.id),
error => this.error = error // TODO: Display error message
);
}

ngOnInit() {
Expand All @@ -60,6 +62,6 @@ export class HeroesComponent implements OnInit {
}

gotoDetail() {
this._router.navigate(['HeroDetail', { id: this.selectedHero.id }]);
this.router.navigate(['/detail/:id', { id: this.selectedHero.id }]);
}
}
14 changes: 4 additions & 10 deletions src/js/main.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
// Imports for loading & configuring the in-memory web api
import { provide } from '@angular/core';
import { XHRBackend } from '@angular/http';

import { InMemoryBackendService, SEED_DATA } from 'angular2-in-memory-web-api/core';
import { InMemoryDataService } from './services/in-memory-data.service';

// The usual bootstrapping imports
import { bootstrap } from '@angular/platform-browser-dynamic';
import { HTTP_PROVIDERS } from '@angular/http';

import { AppComponent } from './components/app.component';
import { APP_ROUTER_PROVIDERS } from './routes/app.routes';

document.addEventListener("DOMContentLoaded", function(event) {
// TODO: register HTTP_PROVIDERS in AppComponent providers
bootstrap(AppComponent, [
APP_ROUTER_PROVIDERS,
HTTP_PROVIDERS,
provide(XHRBackend, { useClass: InMemoryBackendService }), // in-mem server
provide(SEED_DATA, { useClass: InMemoryDataService }), // in-mem server data
]);
])
.catch(err => console.error(err));
});
26 changes: 26 additions & 0 deletions src/js/routes/app.routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { provideRouter, RouterConfig } from '@angular/router';

import { DashboardComponent } from '../components/dashboard.component';
import { HeroesListComponent } from '../components/heroes-list.component';
import { HeroDetailComponent } from '../components/hero-detail.component';


export const routes: RouterConfig = [
// { path: 'crisis-center', component: CrisisCenterComponent },
{
component: DashboardComponent,
path: '',
},
{
component: HeroDetailComponent,
path: 'detail/:id',
},
{
component: HeroesListComponent,
path: 'heroes',
},
];

export const APP_ROUTER_PROVIDERS = [
provideRouter(routes),
];
Loading

0 comments on commit 1018c30

Please sign in to comment.