Skip to content

Instantly share code, notes, and snippets.

@jashmenn
Created July 1, 2016 00:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jashmenn/8638310d284afc3a9e6eb650f7495f60 to your computer and use it in GitHub Desktop.
Save jashmenn/8638310d284afc3a9e6eb650f7495f60 to your computer and use it in GitHub Desktop.
ng-book 2 code diff between rc.2 and rc.4 - https://www.ng-book.com/2
diff --git a/manuscript/code/advanced_components/app/ts/app.ts b/manuscript/code/advanced_components/app/ts/app.ts
index 6db6693..830beb2 100644
--- a/manuscript/code/advanced_components/app/ts/app.ts
+++ b/manuscript/code/advanced_components/app/ts/app.ts
@@ -13,10 +13,10 @@ import {
import { bootstrap } from '@angular/platform-browser-dynamic';
import {
ROUTER_DIRECTIVES,
- ROUTER_PROVIDERS,
- RouteDefinition,
+ RouterConfig,
+ provideRouter,
Router
-} from '@angular/router-deprecated';
+} from '@angular/router';
import {
APP_BASE_HREF,
LocationStrategy,
@@ -47,25 +47,31 @@ import './assets';
* Here's the master list of our examples for this chapter.
*/
let examples: ExampleDef[] = [ /* tslint:disable:max-line-length */
- {label: 'Intro', name: 'Root', path: '/', component: IntroComponent},
- {label: 'Styling', name: 'Styling', path: '/styling', component: StyleSampleApp },
- {label: 'Modifying the Host (Step 1)', name: 'Host1', path: '/host-step-1', component: HostSampleApp1, dev: true},
- {label: 'Modifying the Host (Step 2)', name: 'Host2', path: '/host-step-2', component: HostSampleApp2, dev: true},
- {label: 'Modifying the Host (Step 3)', name: 'Host3', path: '/host-step-3', component: HostSampleApp3, dev: true},
- {label: 'Modifying the Host (Step 4)', name: 'Host4', path: '/host-step-4', component: HostSampleApp4, dev: true},
- {label: 'Modifying the Host', name: 'Host', path: '/host-final', component: HostSampleApp},
- {label: 'Tabs - Component Querying', name: 'Tabs', path: '/tabs', component: TabsSampleApp},
- {label: 'Lifecycle 1 - OnInit / OnDestroy', name: 'Lifecycle1', path: '/lifecycle-hooks-1', component: LifecycleSampleApp1 },
- {label: 'Lifecycle 2 - OnChanges', name: 'Lifecycle2', path: '/lifecycle-hooks-2', component: LifecycleSampleApp2 },
- {label: 'Lifecycle 3 - Differs', name: 'Lifecycle3', path: '/lifecycle-hooks-3', component: LifecycleSampleApp3 },
- {label: 'Lifecycle 4 - Full', name: 'Lifecycle4', path: '/lifecycle-hooks-4', component: LifecycleSampleApp4 },
- {label: 'ngBookFor', name: 'NgBookFor', path: '/ng-book-for', component: ForTemplateSampleApp },
- {label: 'ngBookIf', name: 'NgBookIf', path: '/ng-book-if', component: IfTemplateSampleApp },
- {label: 'Transclusion', name: 'Transclusion', path: '/transclusion', component: TransclusionSampleApp },
+ {label: 'Intro', name: 'Root', path: '', component: IntroComponent},
+ {label: 'Styling', name: 'Styling', path: 'styling', component: StyleSampleApp },
+ {label: 'Modifying the Host (Step 1)', name: 'Host1', path: 'host-step-1', component: HostSampleApp1, dev: true},
+ {label: 'Modifying the Host (Step 2)', name: 'Host2', path: 'host-step-2', component: HostSampleApp2, dev: true},
+ {label: 'Modifying the Host (Step 3)', name: 'Host3', path: 'host-step-3', component: HostSampleApp3, dev: true},
+ {label: 'Modifying the Host (Step 4)', name: 'Host4', path: 'host-step-4', component: HostSampleApp4, dev: true},
+ {label: 'Modifying the Host', name: 'Host', path: 'host-final', component: HostSampleApp},
+ {label: 'Tabs - Component Querying', name: 'Tabs', path: 'tabs', component: TabsSampleApp},
+ {label: 'Lifecycle 1 - OnInit / OnDestroy', name: 'Lifecycle1', path: 'lifecycle-hooks-1', component: LifecycleSampleApp1 },
+ {label: 'Lifecycle 2 - OnChanges', name: 'Lifecycle2', path: 'lifecycle-hooks-2', component: LifecycleSampleApp2 },
+ {label: 'Lifecycle 3 - Differs', name: 'Lifecycle3', path: 'lifecycle-hooks-3', component: LifecycleSampleApp3 },
+ {label: 'Lifecycle 4 - Full', name: 'Lifecycle4', path: 'lifecycle-hooks-4', component: LifecycleSampleApp4 },
+ {label: 'ngBookFor', name: 'NgBookFor', path: 'ng-book-for', component: ForTemplateSampleApp },
+ {label: 'ngBookIf', name: 'NgBookIf', path: 'ng-book-if', component: IfTemplateSampleApp },
+ {label: 'Transclusion', name: 'Transclusion', path: 'transclusion', component: TransclusionSampleApp },
{label: 'Change Detection - OnPush', name: 'ChangeDetectionOnPush', path: 'change-detection-onpush', component: OnPushChangeDetectionSampleApp },
{label: 'Change Detection - Observables', name: 'ChangeDetectionObservables', path: 'change-detection-observ', component: ObservableChangeDetectionSampleApp },
]; /* tslint:enable:max-line-length */
+// dynamically configure the router based on our ExampleDefs
+const routes: RouterConfig = examples
+ .map( (example: ExampleDef) => ({
+ path: example.path, component: example.component, terminal: true
+ }));
+
@Component({
selector: 'advanced-components-app',
directives: [ SidebarComponent, ROUTER_DIRECTIVES ],
@@ -102,19 +108,13 @@ class AdvancedComponentsApp {
constructor(private router: Router) {
this.examples = examples; // store the outer examples
-
- // dynamically configure the router based on our ExampleDefs
- let routeDefinitions: RouteDefinition[] = examples
- .map( (example: ExampleDef) => <RouteDefinition>({
- path: example.path, name: example.name, component: example.component
- }));
- router.config(routeDefinitions);
}
}
bootstrap(AdvancedComponentsApp, [
- ROUTER_PROVIDERS,
+ provideRouter(routes),
provide(APP_BASE_HREF, {useValue: '/'}),
provide(LocationStrategy, {useClass: HashLocationStrategy})
]).catch((err: any) => console.error(err));
+
diff --git a/manuscript/code/advanced_components/app/ts/app/sidebar.ts b/manuscript/code/advanced_components/app/ts/app/sidebar.ts
index 071e670..e12719c 100644
--- a/manuscript/code/advanced_components/app/ts/app/sidebar.ts
+++ b/manuscript/code/advanced_components/app/ts/app/sidebar.ts
@@ -9,10 +9,13 @@ import {
Component,
Input
} from '@angular/core';
+import { Location } from '@angular/common';
import {
ROUTER_DIRECTIVES,
- Router
-} from '@angular/router-deprecated';
+ Router,
+ ActivatedRoute,
+ UrlPathWithParams
+} from '@angular/router';
import { ExampleDef } from './example';
/*
@@ -29,7 +32,7 @@ import { ExampleDef } from './example';
template: `
<a class="item"
[ngClass]="{ active: isActive() }"
- [routerLink]="[item.name]">
+ [routerLink]="[item.path]">
{{ item.label }}
</a>
`
@@ -37,17 +40,14 @@ import { ExampleDef } from './example';
class SidebarItemComponent {
@Input('item') item: ExampleDef;
- constructor(private router: Router) {
+ constructor(private router: Router,
+ private route: ActivatedRoute,
+ private location: Location) {
}
// Checks if this current example is the selected one
isActive(): boolean {
- return this.isRouteActive(this.item.name);
- }
-
- // Here's how you determine if a current route is active in ng2
- isRouteActive(route: string): boolean {
- return this.router.isRouteActive(this.router.generate([route]));
+ return `/${this.item.path}` === this.location.path();
}
}
diff --git a/manuscript/code/advanced_components/package.json b/manuscript/code/advanced_components/package.json
index 4b6c7ec..6aad22d 100644
--- a/manuscript/code/advanced_components/package.json
+++ b/manuscript/code/advanced_components/package.json
@@ -18,14 +18,14 @@
],
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
- "@angular/router-deprecated": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"base64id": "0.1.0",
"core-js": "2.2.2",
"lodash": "3.10.1",
diff --git a/manuscript/code/built_in_components/ng_class/package.json b/manuscript/code/built_in_components/ng_class/package.json
index 96410eb..330197d 100644
--- a/manuscript/code/built_in_components/ng_class/package.json
+++ b/manuscript/code/built_in_components/ng_class/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/built_in_components/ng_for/package.json b/manuscript/code/built_in_components/ng_for/package.json
index 96410eb..330197d 100644
--- a/manuscript/code/built_in_components/ng_for/package.json
+++ b/manuscript/code/built_in_components/ng_for/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/built_in_components/ng_non_bindable/package.json b/manuscript/code/built_in_components/ng_non_bindable/package.json
index 96410eb..330197d 100644
--- a/manuscript/code/built_in_components/ng_non_bindable/package.json
+++ b/manuscript/code/built_in_components/ng_non_bindable/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/built_in_components/ng_style/package.json b/manuscript/code/built_in_components/ng_style/package.json
index 96410eb..330197d 100644
--- a/manuscript/code/built_in_components/ng_style/package.json
+++ b/manuscript/code/built_in_components/ng_style/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/built_in_components/ng_switch/package.json b/manuscript/code/built_in_components/ng_switch/package.json
index 96410eb..330197d 100644
--- a/manuscript/code/built_in_components/ng_switch/package.json
+++ b/manuscript/code/built_in_components/ng_switch/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/conversion/hybrid/package.json b/manuscript/code/conversion/hybrid/package.json
index 8d7ad41..4759839 100644
--- a/manuscript/code/conversion/hybrid/package.json
+++ b/manuscript/code/conversion/hybrid/package.json
@@ -16,13 +16,14 @@
"go": "concurrent \"npm run tsc:w\" \"npm run serve\" "
},
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"@angular/upgrade": "2.0.0-rc.2",
"core-js": "2.2.2",
diff --git a/manuscript/code/dependency_injection/complex/package.json b/manuscript/code/dependency_injection/complex/package.json
index 24be804..5b6395c 100644
--- a/manuscript/code/dependency_injection/complex/package.json
+++ b/manuscript/code/dependency_injection/complex/package.json
@@ -11,13 +11,14 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"core-js": "2.2.2",
diff --git a/manuscript/code/dependency_injection/injector/package.json b/manuscript/code/dependency_injection/injector/package.json
index 3e1c94d..6d23703 100644
--- a/manuscript/code/dependency_injection/injector/package.json
+++ b/manuscript/code/dependency_injection/injector/package.json
@@ -11,13 +11,14 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"core-js": "2.2.2",
diff --git a/manuscript/code/dependency_injection/misc/package.json b/manuscript/code/dependency_injection/misc/package.json
index fa725bb..947503b 100644
--- a/manuscript/code/dependency_injection/misc/package.json
+++ b/manuscript/code/dependency_injection/misc/package.json
@@ -11,13 +11,14 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"core-js": "2.2.2",
diff --git a/manuscript/code/dependency_injection/simple/package.json b/manuscript/code/dependency_injection/simple/package.json
index 07c612d..e59e496 100644
--- a/manuscript/code/dependency_injection/simple/package.json
+++ b/manuscript/code/dependency_injection/simple/package.json
@@ -11,13 +11,14 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"core-js": "2.2.2",
diff --git a/manuscript/code/dependency_injection/value/package.json b/manuscript/code/dependency_injection/value/package.json
index 8ab7814..6c904d4 100644
--- a/manuscript/code/dependency_injection/value/package.json
+++ b/manuscript/code/dependency_injection/value/package.json
@@ -14,13 +14,14 @@
],
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"core-js": "2.2.2",
diff --git a/manuscript/code/first_app/angular2-reddit-base/package.json b/manuscript/code/first_app/angular2-reddit-base/package.json
index efad622..46513bf 100644
--- a/manuscript/code/first_app/angular2-reddit-base/package.json
+++ b/manuscript/code/first_app/angular2-reddit-base/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/first_app/angular2-reddit-completed/package.json b/manuscript/code/first_app/angular2-reddit-completed/package.json
index efad622..46513bf 100644
--- a/manuscript/code/first_app/angular2-reddit-completed/package.json
+++ b/manuscript/code/first_app/angular2-reddit-completed/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/first_app/hello-world/package.json b/manuscript/code/first_app/hello-world/package.json
index a39e0c2..ca429c8 100644
--- a/manuscript/code/first_app/hello-world/package.json
+++ b/manuscript/code/first_app/hello-world/package.json
@@ -10,13 +10,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/forms/app/ts/app.ts b/manuscript/code/forms/app/ts/app.ts
index c43a577..8ce37ac 100644
--- a/manuscript/code/forms/app/ts/app.ts
+++ b/manuscript/code/forms/app/ts/app.ts
@@ -4,7 +4,8 @@
import {
Component
} from '@angular/core';
-import {bootstrap} from '@angular/platform-browser-dynamic';
+import { bootstrap } from '@angular/platform-browser-dynamic';
+import { disableDeprecatedForms, provideForms } from '@angular/forms';
/*
* We're using Webpack to load our CSS which is why we use `require` instead of
@@ -45,7 +46,8 @@ import {DemoFormNgModel} from
DemoFormWithValidationsExplicit,
DemoFormWithCustomValidations,
DemoFormWithEvents,
- DemoFormNgModel],
+ DemoFormNgModel
+ ],
template: `
<div>
<demo-form-ng-model></demo-form-ng-model>
@@ -61,4 +63,8 @@ import {DemoFormNgModel} from
class FormsDemoApp {
}
-bootstrap(FormsDemoApp);
+bootstrap(FormsDemoApp, [
+ disableDeprecatedForms(),
+ provideForms()
+])
+.catch((err: any) => console.error(err));
diff --git a/manuscript/code/forms/app/ts/forms/demo_form_ng_model.ts b/manuscript/code/forms/app/ts/forms/demo_form_ng_model.ts
index 25edd03..d2037f3 100644
--- a/manuscript/code/forms/app/ts/forms/demo_form_ng_model.ts
+++ b/manuscript/code/forms/app/ts/forms/demo_form_ng_model.ts
@@ -1,15 +1,15 @@
import { Component } from '@angular/core';
import {
- CORE_DIRECTIVES,
FORM_DIRECTIVES,
+ REACTIVE_FORM_DIRECTIVES,
FormBuilder,
- ControlGroup,
+ FormGroup,
Validators
-} from '@angular/common';
+} from '@angular/forms';
@Component({
selector: 'demo-form-ng-model',
- directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
+ directives: [FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
template: `
<div class="ui raised segment">
<h2 class="ui header">Demo Form: with ng-model</h2>
@@ -18,7 +18,7 @@ import {
The product name is: {{productName}}
</div>
- <form [ngFormModel]="myForm"
+ <form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form">
@@ -27,7 +27,7 @@ import {
<input type="text"
id="productNameInput"
placeholder="Product Name"
- [ngFormControl]="myForm.find('productName')"
+ [formControl]="myForm.find('productName')"
[(ngModel)]="productName">
</div>
@@ -40,7 +40,7 @@ import {
`
})
export class DemoFormNgModel {
- myForm: ControlGroup;
+ myForm: FormGroup;
productName: string;
constructor(fb: FormBuilder) {
diff --git a/manuscript/code/forms/app/ts/forms/demo_form_sku.ts b/manuscript/code/forms/app/ts/forms/demo_form_sku.ts
index 57256bb..a244de2 100644
--- a/manuscript/code/forms/app/ts/forms/demo_form_sku.ts
+++ b/manuscript/code/forms/app/ts/forms/demo_form_sku.ts
@@ -1,9 +1,9 @@
import { Component } from '@angular/core';
-import { FORM_DIRECTIVES } from '@angular/common';
+
@Component({
selector: 'demo-form-sku',
- directives: [FORM_DIRECTIVES],
+
template: `
<div class="ui raised segment">
<h2 class="ui header">Demo Form: Sku</h2>
@@ -16,7 +16,7 @@ import { FORM_DIRECTIVES } from '@angular/common';
<input type="text"
id="skuInput"
placeholder="SKU"
- ngControl="sku">
+ name="sku" ngModel>
</div>
<button type="submit" class="ui button">Submit</button>
diff --git a/manuscript/code/forms/app/ts/forms/demo_form_sku_with_builder.ts b/manuscript/code/forms/app/ts/forms/demo_form_sku_with_builder.ts
index 0af16b0..e17babf 100644
--- a/manuscript/code/forms/app/ts/forms/demo_form_sku_with_builder.ts
+++ b/manuscript/code/forms/app/ts/forms/demo_form_sku_with_builder.ts
@@ -1,17 +1,18 @@
import { Component } from '@angular/core';
import {
FORM_DIRECTIVES,
+ REACTIVE_FORM_DIRECTIVES,
FormBuilder,
- ControlGroup
-} from '@angular/common';
+ FormGroup
+} from '@angular/forms';
@Component({
selector: 'demo-form-sku-builder',
- directives: [FORM_DIRECTIVES],
+ directives: [FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
template: `
<div class="ui raised segment">
<h2 class="ui header">Demo Form: Sku with Builder</h2>
- <form [ngFormModel]="myForm"
+ <form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form">
@@ -20,7 +21,7 @@ import {
<input type="text"
id="skuInput"
placeholder="SKU"
- [ngFormControl]="myForm.controls['sku']">
+ [formControl]="myForm.controls['sku']">
</div>
<button type="submit" class="ui button">Submit</button>
@@ -29,7 +30,7 @@ import {
`
})
export class DemoFormSkuBuilder {
- myForm: ControlGroup;
+ myForm: FormGroup;
constructor(fb: FormBuilder) {
this.myForm = fb.group({
diff --git a/manuscript/code/forms/app/ts/forms/demo_form_with_custom_validations.ts b/manuscript/code/forms/app/ts/forms/demo_form_with_custom_validations.ts
index a01cca9..60675b1 100644
--- a/manuscript/code/forms/app/ts/forms/demo_form_with_custom_validations.ts
+++ b/manuscript/code/forms/app/ts/forms/demo_form_with_custom_validations.ts
@@ -1,14 +1,14 @@
/* tslint:disable:no-string-literal */
import { Component } from '@angular/core';
import {
- CORE_DIRECTIVES,
FORM_DIRECTIVES,
+ REACTIVE_FORM_DIRECTIVES,
FormBuilder,
- ControlGroup,
+ FormGroup,
Validators,
AbstractControl,
- Control
-} from '@angular/common';
+ FormControl
+} from '@angular/forms';
/**
* Our custom validator
@@ -18,7 +18,7 @@ import {
* - Returns a `StringMap<string, boolean>` where the key is "error code" and
* the value is `true` if it fails
*/
-function skuValidator(control: Control): { [s: string]: boolean } {
+function skuValidator(control: FormControl): { [s: string]: boolean } {
if (!control.value.match(/^123/)) {
return {invalidSku: true};
}
@@ -26,11 +26,11 @@ function skuValidator(control: Control): { [s: string]: boolean } {
@Component({
selector: 'demo-form-with-custom-validations',
- directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
+ directives: [FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
template: `
<div class="ui raised segment">
<h2 class="ui header">Demo Form: with custom validations</h2>
- <form [ngFormModel]="myForm"
+ <form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form">
@@ -40,7 +40,7 @@ function skuValidator(control: Control): { [s: string]: boolean } {
<input type="text"
id="skuInput"
placeholder="SKU"
- [ngFormControl]="sku">
+ [formControl]="sku">
<div *ngIf="!sku.valid"
class="ui error message">SKU is invalid</div>
<div *ngIf="sku.hasError('required')"
@@ -57,7 +57,7 @@ function skuValidator(control: Control): { [s: string]: boolean } {
`
})
export class DemoFormWithCustomValidations {
- myForm: ControlGroup;
+ myForm: FormGroup;
sku: AbstractControl;
constructor(fb: FormBuilder) {
diff --git a/manuscript/code/forms/app/ts/forms/demo_form_with_events.ts b/manuscript/code/forms/app/ts/forms/demo_form_with_events.ts
index 2e9e6de..d612b1c 100644
--- a/manuscript/code/forms/app/ts/forms/demo_form_with_events.ts
+++ b/manuscript/code/forms/app/ts/forms/demo_form_with_events.ts
@@ -1,21 +1,20 @@
-/* tslint:disable:no-string-literal */
import { Component } from '@angular/core';
import {
- CORE_DIRECTIVES,
FORM_DIRECTIVES,
+ REACTIVE_FORM_DIRECTIVES,
FormBuilder,
- ControlGroup,
+ FormGroup,
Validators,
AbstractControl
-} from '@angular/common';
+} from '@angular/forms';
@Component({
selector: 'demo-form-with-events',
- directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
+ directives: [FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
template: `
<div class="ui raised segment">
<h2 class="ui header">Demo Form: with events</h2>
- <form [ngFormModel]="myForm"
+ <form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form">
@@ -26,7 +25,7 @@ import {
class="form-control"
id="skuInput"
placeholder="SKU"
- [ngFormControl]="sku">
+ [formControl]="sku">
<div *ngIf="!sku.valid"
class="ui error message">SKU is invalid</div>
<div *ngIf="sku.hasError('required')"
@@ -42,7 +41,7 @@ import {
`
})
export class DemoFormWithEvents {
- myForm: ControlGroup;
+ myForm: FormGroup;
sku: AbstractControl;
constructor(fb: FormBuilder) {
diff --git a/manuscript/code/forms/app/ts/forms/demo_form_with_validations_explicit.ts b/manuscript/code/forms/app/ts/forms/demo_form_with_validations_explicit.ts
index 89725e1..bbc477f 100644
--- a/manuscript/code/forms/app/ts/forms/demo_form_with_validations_explicit.ts
+++ b/manuscript/code/forms/app/ts/forms/demo_form_with_validations_explicit.ts
@@ -1,21 +1,21 @@
/* tslint:disable:no-string-literal */
import { Component } from '@angular/core';
import {
- CORE_DIRECTIVES,
FORM_DIRECTIVES,
+ REACTIVE_FORM_DIRECTIVES,
FormBuilder,
- ControlGroup,
+ FormGroup,
Validators,
AbstractControl
-} from '@angular/common';
+} from '@angular/forms';
@Component({
selector: 'demo-form-with-validations-explicit',
- directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
+ directives: [FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
template: `
<div class="ui raised segment">
<h2 class="ui header">Demo Form: with validations (explicit)</h2>
- <form [ngFormModel]="myForm"
+ <form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form">
@@ -25,7 +25,7 @@ import {
<input type="text"
id="skuInput"
placeholder="SKU"
- [ngFormControl]="sku">
+ [formControl]="sku">
<div *ngIf="!sku.valid"
class="ui error message">SKU is invalid</div>
<div *ngIf="sku.hasError('required')"
@@ -41,7 +41,7 @@ import {
`
})
export class DemoFormWithValidationsExplicit {
- myForm: ControlGroup;
+ myForm: FormGroup;
sku: AbstractControl;
constructor(fb: FormBuilder) {
diff --git a/manuscript/code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts b/manuscript/code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts
index 5c6bc62..43c1a0f 100644
--- a/manuscript/code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts
+++ b/manuscript/code/forms/app/ts/forms/demo_form_with_validations_shorthand.ts
@@ -1,19 +1,19 @@
import { Component } from '@angular/core';
import {
- CORE_DIRECTIVES,
FORM_DIRECTIVES,
+ REACTIVE_FORM_DIRECTIVES,
FormBuilder,
- ControlGroup,
+ FormGroup,
Validators
-} from '@angular/common';
+} from '@angular/forms';
@Component({
selector: 'demo-form-with-validations-shorthand',
- directives: [CORE_DIRECTIVES, FORM_DIRECTIVES],
+ directives: [FORM_DIRECTIVES, REACTIVE_FORM_DIRECTIVES],
template: `
<div class="ui raised segment">
<h2 class="ui header">Demo Form: with validations (shorthand)</h2>
- <form [ngFormModel]="myForm"
+ <form [formGroup]="myForm"
(ngSubmit)="onSubmit(myForm.value)"
class="ui form">
@@ -23,11 +23,10 @@ import {
<input type="text"
id="skuInput"
placeholder="SKU"
- #sku="ngForm"
- [ngFormControl]="myForm.controls['sku']">
- <div *ngIf="!sku.control.valid"
+ [formControl]="myForm.controls['sku']">
+ <div *ngIf="!myForm.controls['sku'].valid"
class="ui error message">SKU is invalid</div>
- <div *ngIf="sku.control.hasError('required')"
+ <div *ngIf="myForm.controls['sku'].hasError('required')"
class="ui error message">SKU is required</div>
</div>
@@ -40,7 +39,7 @@ import {
`
})
export class DemoFormWithValidationsShorthand {
- myForm: ControlGroup;
+ myForm: FormGroup;
constructor(fb: FormBuilder) {
this.myForm = fb.group({
diff --git a/manuscript/code/forms/package.json b/manuscript/code/forms/package.json
index 29f1bde..59ee606 100644
--- a/manuscript/code/forms/package.json
+++ b/manuscript/code/forms/package.json
@@ -6,18 +6,19 @@
"scripts": {
"clean": "true",
"go": "./node_modules/.bin/webpack-dev-server",
- "test": "karma start"
+ "test": "karma start --single-run"
},
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"bootstrap-sass": "3.3.5",
diff --git a/manuscript/code/forms/test/forms/demo_form_ng_model.spec.ts b/manuscript/code/forms/test/forms/demo_form_ng_model.spec.ts
index cd0d436..e1642ca 100644
--- a/manuscript/code/forms/test/forms/demo_form_ng_model.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_ng_model.spec.ts
@@ -1,30 +1,38 @@
import {
it,
describe,
-
- expect,
-
async,
inject,
- beforeEachProviders
+ addProviders
} from '@angular/core/testing';
-import { TestComponentBuilder } from '@angular/compiler/testing';
-import { FormBuilder } from '@angular/common';
-
+import {
+ disableDeprecatedForms,
+ provideForms,
+ FormBuilder
+} from '@angular/forms';
+import { TestComponentBuilder } from '@angular/core/testing';
import { DemoFormNgModel } from '../../app/ts/forms/demo_form_ng_model';
-beforeEachProviders(() => { return [FormBuilder]; });
-
describe('DemoFormNgModel', () => {
+ beforeEach(() => {
+ addProviders([
+ disableDeprecatedForms(),
+ provideForms(),
+ FormBuilder
+ ]);
+ });
+
it('requires product name', async(inject([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(DemoFormNgModel).then((fixture) => {
+ return tcb.createAsync(DemoFormNgModel)
+ .then((fixture) => {
let comp = fixture.debugElement.componentInstance;
let el = fixture.debugElement.nativeElement;
// error message is displayed when product name is empty
comp.productName = '';
fixture.detectChanges();
- expect(el.querySelector('.ui.error.message')).toHaveText('Form is invalid');
+ expect(el.querySelector('.ui.error.message').innerHTML)
+ .toContain('Form is invalid');
// error message is not present when product name has a value
comp.productName = 'something';
diff --git a/manuscript/code/forms/test/forms/demo_form_sku.spec.ts b/manuscript/code/forms/test/forms/demo_form_sku.spec.ts
index 897ff94..08dde3f 100644
--- a/manuscript/code/forms/test/forms/demo_form_sku.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_sku.spec.ts
@@ -1,49 +1,42 @@
import {
it,
describe,
-
expect,
inject,
-
fakeAsync,
tick,
-
-
-
} from '@angular/core/testing';
-import { TestComponentBuilder, ComponentFixture } from '@angular/compiler/testing';
-import { dispatchEvent } from '@angular/platform-browser/testing';
+import { TestComponentBuilder, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser/src/dom/debug/by';
-
import { DemoFormSku } from '../../app/ts/forms/demo_form_sku';
-
-describe('DemoFormSku', () => {
- var _console;
- var fakeConsole;
- var el, input, form;
-
+import {
+ dispatchEvent,
+ ConsoleSpy
+} from '../util';
+
+describe('DemoFormSku Component', () => {
+ let originalConsole, fakeConsole;
+ let el, input, form;
+
beforeEach(() => {
- // declare a fake console to track all the logs
- fakeConsole = {};
- fakeConsole._logs = [];
- fakeConsole.log = (...theArgs) => fakeConsole._logs.push(theArgs.join(' '));
- fakeConsole.warn = (...theArgs) => fakeConsole._logs.push(theArgs.join(' '));
- // replace the real console with our fake version
- _console = window.console;
+ // replace the real window.console with our spy
+ fakeConsole = new ConsoleSpy();
+ originalConsole = window.console;
(<any>window).console = fakeConsole;
});
- // restores the real console
- afterAll(() => (<any>window).console = _console);
+ // restore real console
+ afterAll(() => (<any>window).console = originalConsole);
function createComponent(tcb: TestComponentBuilder): Promise<ComponentFixture<any>> {
- return tcb.createAsync(DemoFormSku).then((fixture) => {
- el = fixture.debugElement.nativeElement;
- input = fixture.debugElement.query(By.css("input")).nativeElement;
- form = fixture.debugElement.query(By.css("form")).nativeElement;
- fixture.detectChanges();
+ return tcb.createAsync(DemoFormSku)
+ .then((fixture) => {
+ el = fixture.debugElement.nativeElement;
+ input = fixture.debugElement.query(By.css('input')).nativeElement;
+ form = fixture.debugElement.query(By.css('form')).nativeElement;
+ fixture.detectChanges();
- return fixture;
+ return fixture;
});
}
@@ -59,7 +52,7 @@ describe('DemoFormSku', () => {
dispatchEvent(form, 'submit');
tick();
- expect(fakeConsole._logs).toContain('you submitted value: [object Object]');
+ expect(fakeConsole.logs).toContain('you submitted value: [object Object]');
});
})
));
diff --git a/manuscript/code/forms/test/forms/demo_form_sku_with_builder.spec.ts b/manuscript/code/forms/test/forms/demo_form_sku_with_builder.spec.ts
index 77ccc19..f12893c 100644
--- a/manuscript/code/forms/test/forms/demo_form_sku_with_builder.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_sku_with_builder.spec.ts
@@ -1,25 +1,33 @@
import {
it,
describe,
-
expect,
-
inject,
- async,
- beforeEachProviders
+ async
} from '@angular/core/testing';
-import { TestComponentBuilder } from '@angular/compiler/testing';
-import { FormBuilder } from '@angular/common';
-
+import { TestComponentBuilder } from '@angular/core/testing';
+import {
+ disableDeprecatedForms,
+ provideForms,
+ FormBuilder
+} from '@angular/forms';
import { DemoFormSkuBuilder } from '../../app/ts/forms/demo_form_sku_with_builder';
-beforeEachProviders(() => {
- return [FormBuilder];
-});
-
describe('DemoFormSkuBuilder', () => {
+ let providerArr: any[];
+ beforeEach(() => {
+ providerArr = [
+ disableDeprecatedForms(),
+ provideForms(),
+ FormBuilder
+ ];
+ });
+
it('initializes sku', async(inject([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(DemoFormSkuBuilder).then((fixture) => {
+ let fb = new FormBuilder();
+ return tcb.overrideProviders(DemoFormSkuBuilder, providerArr)
+ .createAsync(DemoFormSkuBuilder)
+ .then((fixture) => {
let comp = fixture.debugElement.componentInstance;
let el = fixture.debugElement.nativeElement;
@@ -32,4 +40,5 @@ describe('DemoFormSkuBuilder', () => {
expect(el.querySelector('form input').value).toEqual('ABC123');
});
})));
+
});
diff --git a/manuscript/code/forms/test/forms/demo_form_with_custom_validations.spec.ts b/manuscript/code/forms/test/forms/demo_form_with_custom_validations.spec.ts
index 1632a71..adc3f05 100644
--- a/manuscript/code/forms/test/forms/demo_form_with_custom_validations.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_with_custom_validations.spec.ts
@@ -1,28 +1,41 @@
import {
it,
describe,
-
- expect,
-
inject,
async,
- beforeEachProviders,
-
+ addProviders,
+} from '@angular/core/testing';
+import {
+ disableDeprecatedForms,
+ provideForms,
+ FormBuilder
+} from '@angular/forms';
+import {
+ TestComponentBuilder,
+ ComponentFixture
} from '@angular/core/testing';
-import { TestComponentBuilder, ComponentFixture } from '@angular/compiler/testing';
-import { dispatchEvent } from '@angular/platform-browser/testing';
+import { dispatchEvent } from '../util';
import { By } from '@angular/platform-browser/src/dom/debug/by';
-import { FormBuilder } from '@angular/common';
-
-import { DemoFormWithCustomValidations } from '../../app/ts/forms/demo_form_with_custom_validations';
+import {
+ DemoFormWithCustomValidations
+} from '../../app/ts/forms/demo_form_with_custom_validations';
describe('DemoFormWithCustomValidations', () => {
var el, input, form;
+ let providerArr: any[];
- beforeEachProviders(() => { return [FormBuilder]; });
+ beforeEach(() => {
+ addProviders([
+ disableDeprecatedForms(),
+ provideForms(),
+ FormBuilder
+ ]);
+ });
function createComponent(tcb: TestComponentBuilder): Promise<ComponentFixture<any>> {
- return tcb.createAsync(DemoFormWithCustomValidations).then((fixture) => {
+ return tcb.overrideProviders(DemoFormWithCustomValidations, providerArr)
+ .createAsync(DemoFormWithCustomValidations)
+ .then((fixture) => {
el = fixture.debugElement.nativeElement;
input = fixture.debugElement.query(By.css("input")).nativeElement;
form = fixture.debugElement.query(By.css("form")).nativeElement;
@@ -32,34 +45,37 @@ describe('DemoFormWithCustomValidations', () => {
});
}
- it('displays errors with no sku', async(inject([TestComponentBuilder], (tcb) => {
+ it('displays errors with no sku',
+ async(inject([TestComponentBuilder], (tcb) => {
return createComponent(tcb).then((fixture) => {
input.value = '';
dispatchEvent(input, 'input');
fixture.detectChanges();
let msgs = el.querySelectorAll('.ui.error.message');
- expect(msgs[0]).toHaveText('SKU is invalid');
- expect(msgs[1]).toHaveText('SKU is required');
- expect(msgs[2]).toHaveText('SKU must begin with 123');
- expect(msgs[3]).toHaveText('Form is invalid');
+ expect(msgs[0].innerHTML).toContain('SKU is invalid');
+ expect(msgs[1].innerHTML).toContain('SKU is required');
+ expect(msgs[2].innerHTML).toContain('SKU must begin with <tt>123</tt>');
+ expect(msgs[3].innerHTML).toContain('Form is invalid');
});
})));
- it('removes the required error when sku has a value', async(inject([TestComponentBuilder], (tcb) => {
+ it('removes the required error when sku has a value',
+ async(inject([TestComponentBuilder], (tcb) => {
return createComponent(tcb).then((fixture) => {
input.value = 'ABC';
dispatchEvent(input, 'input');
fixture.detectChanges();
let msgs = el.querySelectorAll('.ui.error.message');
- expect(msgs[0]).toHaveText('SKU is invalid');
- expect(msgs[1]).toHaveText('SKU must begin with 123');
- expect(msgs[2]).toHaveText('Form is invalid');
+ expect(msgs[0].innerHTML).toContain('SKU is invalid');
+ expect(msgs[1].innerHTML).toContain('SKU must begin with <tt>123</tt>');
+ expect(msgs[2].innerHTML).toContain('Form is invalid');
});
})));
- it('removes all errors when sku starts with 123', async(inject([TestComponentBuilder], (tcb) => {
+ it('removes all errors when sku starts with 123',
+ async(inject([TestComponentBuilder], (tcb) => {
return createComponent(tcb).then((fixture) => {
input.value = '123ABC';
dispatchEvent(input, 'input');
diff --git a/manuscript/code/forms/test/forms/demo_form_with_events.spec.ts b/manuscript/code/forms/test/forms/demo_form_with_events.spec.ts
index b8e4a0c..ba20d0b 100644
--- a/manuscript/code/forms/test/forms/demo_form_with_events.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_with_events.spec.ts
@@ -1,58 +1,63 @@
import {
it,
describe,
-
- expect,
inject,
async,
-
fakeAsync,
tick,
- beforeEachProviders,
-
+ addProviders
} from '@angular/core/testing';
-import { TestComponentBuilder, ComponentFixture } from '@angular/compiler/testing';
-import { dispatchEvent } from '@angular/platform-browser/testing';
+import {
+ TestComponentBuilder,
+ ComponentFixture
+} from '@angular/core/testing';
+import {
+ disableDeprecatedForms,
+ provideForms,
+ FormBuilder
+} from '@angular/forms';
import { By } from '@angular/platform-browser/src/dom/debug/by';
-import { FormBuilder } from '@angular/common';
-
import { DemoFormWithEvents } from '../../app/ts/forms/demo_form_with_events';
+import {
+ dispatchEvent,
+ ConsoleSpy
+} from '../util';
describe('DemoFormWithEvents', () => {
- var _console;
- var fakeConsole;
- var el, input, form;
+ let originalConsole, fakeConsole;
+ let el, input, form;
beforeEach(() => {
- // declare a fake console to track all the logs
- fakeConsole = {};
- fakeConsole._logs = [];
- fakeConsole.log = (...theArgs) => fakeConsole._logs.push(theArgs.join(' '));
-
- // replace the real console with our fake version
- _console = window.console;
+ // replace the real window.console with our spy
+ fakeConsole = new ConsoleSpy();
+ originalConsole = window.console;
(<any>window).console = fakeConsole;
+
+ addProviders([
+ disableDeprecatedForms(),
+ provideForms(),
+ FormBuilder
+ ]);
});
// restores the real console
- afterAll(() => (<any>window).console = _console);
-
- beforeEachProviders(() => {
- return [FormBuilder];
- });
+ afterAll(() => (<any>window).console = originalConsole);
- function createComponent(tcb: TestComponentBuilder): Promise<ComponentFixture<any>> {
- return tcb.createAsync(DemoFormWithEvents).then((fixture) => {
+ function createComponent(tcb: TestComponentBuilder):
+ Promise<ComponentFixture<any>> {
+ return tcb.createAsync(DemoFormWithEvents)
+ .then((fixture) => {
el = fixture.debugElement.nativeElement;
- input = fixture.debugElement.query(By.css("input")).nativeElement;
- form = fixture.debugElement.query(By.css("form")).nativeElement;
+ input = fixture.debugElement.query(By.css('input')).nativeElement;
+ form = fixture.debugElement.query(By.css('form')).nativeElement;
fixture.detectChanges();
return fixture;
});
}
- it('displays errors with no sku', async(inject([TestComponentBuilder], (tcb) => {
+ it('displays errors with no sku',
+ async(inject([TestComponentBuilder], (tcb) => {
return createComponent(tcb).then((fixture) => {
input.value = '';
dispatchEvent(input, 'input');
@@ -60,12 +65,13 @@ describe('DemoFormWithEvents', () => {
// no value on sku field, all error messages are displayed
let msgs = el.querySelectorAll('.ui.error.message');
- expect(msgs[0]).toHaveText('SKU is invalid');
- expect(msgs[1]).toHaveText('SKU is required');
+ expect(msgs[0].innerHTML).toContain('SKU is invalid');
+ expect(msgs[1].innerHTML).toContain('SKU is required');
});
})));
- it('displays no errors when sku has a value', async(inject([TestComponentBuilder], (tcb) => {
+ it('displays no errors when sku has a value',
+ async(inject([TestComponentBuilder], (tcb) => {
return createComponent(tcb).then((fixture) => {
input.value = 'XYZ';
dispatchEvent(input, 'input');
@@ -83,7 +89,7 @@ describe('DemoFormWithEvents', () => {
dispatchEvent(input, 'input');
tick();
- expect(fakeConsole._logs).toContain('sku changed to: XYZ');
+ expect(fakeConsole.logs).toContain('sku changed to: XYZ');
});
})
));
@@ -95,7 +101,7 @@ describe('DemoFormWithEvents', () => {
dispatchEvent(input, 'input');
tick();
- expect(fakeConsole._logs).toContain('form changed to: [object Object]');
+ expect(fakeConsole.logs).toContain('form changed to: [object Object]');
});
})
));
@@ -111,7 +117,7 @@ describe('DemoFormWithEvents', () => {
dispatchEvent(form, 'submit');
tick();
- expect(fakeConsole._logs).toContain('you submitted value: ABC');
+ expect(fakeConsole.logs).toContain('you submitted value: ABC');
});
})
));
diff --git a/manuscript/code/forms/test/forms/demo_form_with_events_bad.spec.ts b/manuscript/code/forms/test/forms/demo_form_with_events_bad.spec.ts
index 76ef231..c5a0c75 100644
--- a/manuscript/code/forms/test/forms/demo_form_with_events_bad.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_with_events_bad.spec.ts
@@ -1,52 +1,55 @@
import {
it,
describe,
-
expect,
inject,
-
-
fakeAsync,
tick,
- beforeEachProviders
-
+ addProviders
} from '@angular/core/testing';
-import { TestComponentBuilder } from '@angular/compiler/testing';
-import { dispatchEvent } from '@angular/platform-browser/testing';
+import {
+ TestComponentBuilder,
+ ComponentFixture
+} from '@angular/core/testing';
+import {
+ disableDeprecatedForms,
+ provideForms,
+ FormBuilder
+} from '@angular/forms';
import { By } from '@angular/platform-browser/src/dom/debug/by';
-import { FormBuilder } from '@angular/common';
-
import { DemoFormWithEvents } from '../../app/ts/forms/demo_form_with_events';
+import {
+ dispatchEvent,
+ ConsoleSpy
+} from '../util';
describe('DemoFormWithEvents (bad)', () => {
- var _console;
- var fakeConsole;
+ var originalConsole, fakeConsole;
var el, input, form;
beforeEach(() => {
- // declare a fake console to track all the logs
- fakeConsole = {};
- fakeConsole._logs = [];
- fakeConsole.log = (...theArgs) => fakeConsole._logs.push(theArgs.join(' '));
-
- // replace the real console with our fake version
- _console = window.console;
+ // replace the real window.console with our spy
+ fakeConsole = new ConsoleSpy();
+ originalConsole = window.console;
(<any>window).console = fakeConsole;
+
+ addProviders([
+ disableDeprecatedForms(),
+ provideForms(),
+ FormBuilder
+ ]);
});
// restores the real console
- afterAll(() => (<any>window).console = _console);
-
- beforeEachProviders(() => {
- return [FormBuilder];
- });
+ afterAll(() => (<any>window).console = originalConsole);
- it('validates and trigger events', inject([TestComponentBuilder],
+ it('validates and triggers events', inject([TestComponentBuilder],
fakeAsync((tcb) => {
- tcb.createAsync(DemoFormWithEvents).then((fixture) => {
+ tcb.createAsync(DemoFormWithEvents)
+ .then((fixture) => {
let el = fixture.debugElement.nativeElement;
- let input = fixture.debugElement.query(By.css("input")).nativeElement;
- let form = fixture.debugElement.query(By.css("form")).nativeElement;
+ let input = fixture.debugElement.query(By.css('input')).nativeElement;
+ let form = fixture.debugElement.query(By.css('form')).nativeElement;
fixture.detectChanges();
input.value = '';
@@ -56,8 +59,8 @@ describe('DemoFormWithEvents (bad)', () => {
// no value on sku field, all error messages are displayed
let msgs = el.querySelectorAll('.ui.error.message');
- expect(msgs[0]).toHaveText('SKU is invalid');
- expect(msgs[1]).toHaveText('SKU is required');
+ expect(msgs[0].innerHTML).toContain('SKU is invalid');
+ expect(msgs[1].innerHTML).toContain('SKU is required');
// displays no errors when sku has a value
input.value = 'XYZ';
@@ -73,7 +76,7 @@ describe('DemoFormWithEvents (bad)', () => {
tick();
// checks for the form submitted message
- expect(fakeConsole._logs).toContain('you submitted value: XYZ');
+ expect(fakeConsole.logs).toContain('you submitted value: XYZ');
});
})
));
diff --git a/manuscript/code/forms/test/forms/demo_form_with_validations_explicit.spec.ts b/manuscript/code/forms/test/forms/demo_form_with_validations_explicit.spec.ts
index 6c68648..74e37e9 100644
--- a/manuscript/code/forms/test/forms/demo_form_with_validations_explicit.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_with_validations_explicit.spec.ts
@@ -1,32 +1,41 @@
import {
it,
describe,
-
expect,
-
inject,
async,
- beforeEachProviders,
-
+ addProviders
} from '@angular/core/testing';
import {
- CORE_DIRECTIVES,
- FORM_DIRECTIVES,
-} from '@angular/common';
-import { TestComponentBuilder, ComponentFixture } from '@angular/compiler/testing';
-import { dispatchEvent } from '@angular/platform-browser/testing';
+ TestComponentBuilder,
+ ComponentFixture
+} from '@angular/core/testing';
+import {
+ disableDeprecatedForms,
+ provideForms,
+ FormBuilder
+} from '@angular/forms';
import { By } from '@angular/platform-browser/src/dom/debug/by';
-import { FormBuilder } from '@angular/common';
-
import { DemoFormWithValidationsExplicit } from '../../app/ts/forms/demo_form_with_validations_explicit';
+import {
+ dispatchEvent,
+ ConsoleSpy
+} from '../util';
describe('DemoFormWithValidationsExplicit', () => {
- var el, input, form;
+ let el, input, form;
- beforeEachProviders(() => { return [FormBuilder]; });
+ beforeEach(() => {
+ addProviders([
+ disableDeprecatedForms(),
+ provideForms(),
+ FormBuilder
+ ]);
+ });
function createComponent(tcb: TestComponentBuilder): Promise<ComponentFixture<any>> {
- return tcb.createAsync(DemoFormWithValidationsExplicit).then((fixture) => {
+ return tcb.createAsync(DemoFormWithValidationsExplicit)
+ .then((fixture) => {
el = fixture.debugElement.nativeElement;
input = fixture.debugElement.query(By.css("input")).nativeElement;
form = fixture.debugElement.query(By.css("form")).nativeElement;
@@ -43,8 +52,8 @@ describe('DemoFormWithValidationsExplicit', () => {
fixture.detectChanges();
let msgs = el.querySelectorAll('.ui.error.message');
- expect(msgs[0]).toHaveText('SKU is invalid');
- expect(msgs[1]).toHaveText('SKU is required');
+ expect(msgs[0].innerHTML).toContain('SKU is invalid');
+ expect(msgs[1].innerHTML).toContain('SKU is required');
});
})));
diff --git a/manuscript/code/forms/test/forms/demo_form_with_validations_shorthand.spec.ts b/manuscript/code/forms/test/forms/demo_form_with_validations_shorthand.spec.ts
index 0c9bba7..24f5b59 100644
--- a/manuscript/code/forms/test/forms/demo_form_with_validations_shorthand.spec.ts
+++ b/manuscript/code/forms/test/forms/demo_form_with_validations_shorthand.spec.ts
@@ -1,50 +1,52 @@
import {
it,
describe,
-
expect,
inject,
async,
fakeAsync,
tick,
-
- beforeEachProviders,
-
+ addProviders
+} from '@angular/core/testing';
+import {
+ TestComponentBuilder,
+ ComponentFixture
} from '@angular/core/testing';
import {
- CORE_DIRECTIVES,
- FORM_DIRECTIVES,
-} from '@angular/common';
-import { TestComponentBuilder, ComponentFixture } from '@angular/compiler/testing';
-import { dispatchEvent } from '@angular/platform-browser/testing';
+ disableDeprecatedForms,
+ provideForms,
+ FormBuilder
+} from '@angular/forms';
import { By } from '@angular/platform-browser/src/dom/debug/by';
-import { FormBuilder } from '@angular/common';
-
import { DemoFormWithValidationsShorthand } from '../../app/ts/forms/demo_form_with_validations_shorthand';
+import {
+ dispatchEvent,
+ ConsoleSpy
+} from '../util';
describe('DemoFormWithValidationsShorthand', () => {
- var _console;
- var fakeConsole;
- var el, input, form;
+ let originalConsole, fakeConsole;
+ let el, input, form;
beforeEach(() => {
- // declare a fake console to track all the logs
- fakeConsole = {};
- fakeConsole._logs = [];
- fakeConsole.log = (...theArgs) => fakeConsole._logs.push(theArgs.join(' '));
-
- // replace the real console with our fake version
- _console = window.console;
+ // replace the real window.console with our spy
+ fakeConsole = new ConsoleSpy();
+ originalConsole = window.console;
(<any>window).console = fakeConsole;
- });
- // restores the real console
- afterAll(() => (<any>window).console = _console);
+ addProviders([
+ disableDeprecatedForms(),
+ provideForms(),
+ FormBuilder
+ ]);
+ });
- beforeEachProviders(() => { return [FormBuilder]; });
+ // restore real console
+ afterAll(() => (<any>window).console = originalConsole);
function createComponent(tcb: TestComponentBuilder): Promise<ComponentFixture<any>> {
- return tcb.createAsync(DemoFormWithValidationsShorthand).then((fixture) => {
+ return tcb.createAsync(DemoFormWithValidationsShorthand)
+ .then((fixture) => {
el = fixture.debugElement.nativeElement;
input = fixture.debugElement.query(By.css("input")).nativeElement;
form = fixture.debugElement.query(By.css("form")).nativeElement;
@@ -62,8 +64,8 @@ describe('DemoFormWithValidationsShorthand', () => {
// no value on sku field, all error messages are displayed
let msgs = el.querySelectorAll('.ui.error.message');
- expect(msgs[0]).toHaveText('SKU is invalid');
- expect(msgs[1]).toHaveText('SKU is required');
+ expect(msgs[0].innerHTML).toContain('SKU is invalid');
+ expect(msgs[1].innerHTML).toContain('SKU is required');
});
})));
@@ -89,7 +91,7 @@ describe('DemoFormWithValidationsShorthand', () => {
dispatchEvent(form, 'submit');
tick();
- expect(fakeConsole._logs).toContain('you submitted value: XYZ');
+ expect(fakeConsole.logs).toContain('you submitted value: XYZ');
});
})
));
diff --git a/manuscript/code/forms/test/util.ts b/manuscript/code/forms/test/util.ts
new file mode 100644
index 0000000..c5b1cb1
--- /dev/null
+++ b/manuscript/code/forms/test/util.ts
@@ -0,0 +1,19 @@
+/*
+ * Utility functions for our browser tests
+ */
+import { getDOM } from '@angular/platform-browser/src/dom/dom_adapter';
+
+export function dispatchEvent(element: any, eventType: any) {
+ getDOM().dispatchEvent(element, getDOM().createEvent(eventType));
+}
+
+export class ConsoleSpy {
+ public logs: string[] = [];
+ log(...args) {
+ this.logs.push(args.join(' '));
+ }
+ warn(...args) {
+ this.log(...args);
+ }
+}
+
diff --git a/manuscript/code/how_angular_works/inventory_app/package.json b/manuscript/code/how_angular_works/inventory_app/package.json
index 7b1fd25..72843b3 100644
--- a/manuscript/code/how_angular_works/inventory_app/package.json
+++ b/manuscript/code/how_angular_works/inventory_app/package.json
@@ -11,13 +11,14 @@
},
"license": "ISC",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"core-js": "2.2.2",
"es6-shim": "0.35.0",
diff --git a/manuscript/code/http/package.json b/manuscript/code/http/package.json
index 12b3819..42465f1 100644
--- a/manuscript/code/http/package.json
+++ b/manuscript/code/http/package.json
@@ -6,18 +6,19 @@
"scripts": {
"go": "./node_modules/.bin/webpack-dev-server --display-reasons --display-chunks",
"clean": "true",
- "test": "karma start"
+ "test": "karma start --single-run"
},
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"core-js": "2.2.2",
diff --git a/manuscript/code/http/test/MoreHTTPRequests.spec.ts b/manuscript/code/http/test/MoreHTTPRequests.spec.ts
index c1c03f7..76c23d5 100644
--- a/manuscript/code/http/test/MoreHTTPRequests.spec.ts
+++ b/manuscript/code/http/test/MoreHTTPRequests.spec.ts
@@ -1,44 +1,45 @@
-import {provide} from '@angular/core';
+import { provide } from '@angular/core';
import {
it,
describe,
expect,
inject,
+ addProviders,
async,
- afterEach,
- beforeEachProviders,
+ TestComponentBuilder
} from '@angular/core/testing';
-import {TestComponentBuilder} from '@angular/compiler/testing';
import {MockBackend} from '@angular/http/testing';
import {
Http,
ConnectionBackend,
BaseRequestOptions,
Response,
- ResponseOptions,
RequestMethod,
} from '@angular/http';
import { MoreHTTPRequests } from '../app/ts/components/MoreHTTPRequests';
-beforeEachProviders(() => {
- return [
- BaseRequestOptions,
- MockBackend,
- provide(Http, {useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => {
- return new Http(backend, defaultOptions);
- }, deps: [MockBackend, BaseRequestOptions]}),
- ]
-});
-
describe('MoreHTTPRequests', () => {
+ beforeEach(() => {
+ addProviders([
+ BaseRequestOptions,
+ MockBackend,
+ provide(Http, {
+ useFactory: (backend: ConnectionBackend,
+ defaultOptions: BaseRequestOptions) => {
+ return new Http(backend, defaultOptions);
+ }, deps: [MockBackend, BaseRequestOptions]}),
+ ]);
+ });
+
it('performs a POST',
async(inject([TestComponentBuilder, MockBackend], (tcb, backend) => {
return tcb.createAsync(MoreHTTPRequests).then((fixture) => {
let comp = fixture.debugElement.componentInstance;
backend.connections.subscribe(c => {
- expect(c.request.url).toBe('http://jsonplaceholder.typicode.com/posts');
+ expect(c.request.url)
+ .toBe('http://jsonplaceholder.typicode.com/posts');
expect(c.request.method).toBe(RequestMethod.Post);
c.mockRespond(new Response(<any>{body: '{"response": "OK"}'}));
});
@@ -55,7 +56,8 @@ describe('MoreHTTPRequests', () => {
let comp = fixture.debugElement.componentInstance;
backend.connections.subscribe(c => {
- expect(c.request.url).toBe('http://jsonplaceholder.typicode.com/posts/1');
+ expect(c.request.url)
+ .toBe('http://jsonplaceholder.typicode.com/posts/1');
expect(c.request.method).toBe(RequestMethod.Delete);
c.mockRespond(new Response(<any>{body: '{"response": "OK"}'}));
});
@@ -72,7 +74,8 @@ describe('MoreHTTPRequests', () => {
let comp = fixture.debugElement.componentInstance;
backend.connections.subscribe(c => {
- expect(c.request.url).toBe('http://jsonplaceholder.typicode.com/posts/1');
+ expect(c.request.url)
+ .toBe('http://jsonplaceholder.typicode.com/posts/1');
expect(c.request.headers.has('X-API-TOKEN')).toBeTruthy();
expect(c.request.headers.get('X-API-TOKEN')).toEqual('ng-book');
c.mockRespond(new Response(<any>{body: '{"response": "OK"}'}));
diff --git a/manuscript/code/http/test/YouTubeSearchComponentAfter.spec.ts b/manuscript/code/http/test/YouTubeSearchComponentAfter.spec.ts
index 2b68859..1fe8157 100644
--- a/manuscript/code/http/test/YouTubeSearchComponentAfter.spec.ts
+++ b/manuscript/code/http/test/YouTubeSearchComponentAfter.spec.ts
@@ -11,7 +11,7 @@ import {
beforeEach,
beforeEachProviders
} from '@angular/core/testing';
-import {TestComponentBuilder} from '@angular/compiler/testing';
+import {TestComponentBuilder} from '@angular/core/testing';
import {MockBackend} from '@angular/http/testing';
import {
Http,
diff --git a/manuscript/code/http/test/YouTubeSearchComponentBefore.spec.ts b/manuscript/code/http/test/YouTubeSearchComponentBefore.spec.ts
index 76e6783..5e0bd1e 100644
--- a/manuscript/code/http/test/YouTubeSearchComponentBefore.spec.ts
+++ b/manuscript/code/http/test/YouTubeSearchComponentBefore.spec.ts
@@ -6,18 +6,14 @@ import {
inject,
fakeAsync,
tick,
- afterEach,
- beforeEachProviders
+ addProviders
} from '@angular/core/testing';
-import {TestComponentBuilder} from '@angular/compiler/testing';
import {MockBackend} from '@angular/http/testing';
import {
Http,
ConnectionBackend,
BaseRequestOptions,
- Response,
- ResponseOptions,
- RequestMethod,
+ Response
} from '@angular/http';
import {
@@ -27,23 +23,27 @@ import {
} from '../app/ts/components/YouTubeSearchComponent';
describe('MoreHTTPRequests (before)', () => {
- beforeEachProviders(() => {
- return [
+ beforeEach(() => {
+ addProviders([
YouTubeService,
BaseRequestOptions,
MockBackend,
provide(YOUTUBE_API_KEY, {useValue: 'YOUTUBE_API_KEY'}),
provide(YOUTUBE_API_URL, {useValue: 'YOUTUBE_API_URL'}),
- provide(Http, {useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => {
- return new Http(backend, defaultOptions);
- }, deps: [MockBackend, BaseRequestOptions]}),
- ]
+ provide(Http, {
+ useFactory: (backend: ConnectionBackend,
+ defaultOptions: BaseRequestOptions) => {
+ return new Http(backend, defaultOptions);
+ },
+ deps: [MockBackend, BaseRequestOptions]
+ }),
+ ]);
});
describe('search', () => {
it('parses YouTube response',
inject([YouTubeService, MockBackend], fakeAsync((service, backend) => {
- var res;
+ let res;
backend.connections.subscribe(c => {
c.mockRespond(new Response(<any>{
@@ -57,12 +57,7 @@ describe('MoreHTTPRequests (before)', () => {
"description": "DESCRIPTION",
"thumbnails": {
"high": { "url": "THUMBNAIL_URL" }
- }
- }
- }
- ]
- }
- `
+ }}}]}`
}));
});
diff --git a/manuscript/code/routes/auth/app/ts/app.ts b/manuscript/code/routes/auth/app/ts/app.ts
index 174eab8..57e6f10 100644
--- a/manuscript/code/routes/auth/app/ts/app.ts
+++ b/manuscript/code/routes/auth/app/ts/app.ts
@@ -4,12 +4,12 @@
import {provide, Component} from '@angular/core';
import {bootstrap} from '@angular/platform-browser-dynamic';
import {
+ provideRouter,
ROUTER_DIRECTIVES,
- ROUTER_PROVIDERS,
-
Router,
- RouteConfig,
-} from '@angular/router-deprecated';
+ RouterConfig,
+} from '@angular/router';
+import {provideForms} from '@angular/forms';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
/*
@@ -25,6 +25,7 @@ import {ProtectedComponent} from 'components/ProtectedComponent';
* Services
*/
import {AUTH_PROVIDERS} from 'services/AuthService';
+import {LoggedInGuard} from 'guards/loggedIn.guard';
/*
* Webpack
@@ -39,10 +40,10 @@ require('css/styles.scss');
<div class="container">
<h1>Router Sample</h1>
<div class="navLinks">
- <a [routerLink]="['/Home']">Home</a>
- <a [routerLink]="['/About']">About</a>
- <a [routerLink]="['/Contact']">Contact us</a>
- <a [routerLink]="['/Protected']">Protected</a>
+ <a [routerLink]="['/home']">Home</a>
+ <a [routerLink]="['/about']">About</a>
+ <a [routerLink]="['/contact']">Contact us</a>
+ <a [routerLink]="['/protected']">Protected</a>
</div>
</div>
</div>
@@ -59,20 +60,24 @@ require('css/styles.scss');
</div>
`
})
-@RouteConfig([
- { path: '/', name: 'root', redirectTo: ['Home'] },
- { path: '/home', name: 'Home', component: HomeComponent },
- { path: '/about', name: 'About', component: AboutComponent },
- { path: '/contact', name: 'Contact', component: ContactComponent },
- { path: '/protected', name: 'Protected', component: ProtectedComponent },
-])
class RoutesDemoApp {
constructor(public router: Router) {
}
}
+const routes: RouterConfig = [
+ { path: '', redirectTo: 'home', terminal: true },
+ { path: 'home', component: HomeComponent },
+ { path: 'about', component: AboutComponent },
+ { path: 'contact', component: ContactComponent },
+ { path: 'protected', component: ProtectedComponent,
+ canActivate: [LoggedInGuard]}
+];
+
bootstrap(RoutesDemoApp, [
- ROUTER_PROVIDERS,
+ provideRouter(routes),
AUTH_PROVIDERS,
- provide(LocationStrategy, {useClass: HashLocationStrategy})
+ LoggedInGuard,
+ provide(LocationStrategy, {useClass: HashLocationStrategy}),
+ provideForms()
]);
diff --git a/manuscript/code/routes/auth/app/ts/components/LoginComponent.ts b/manuscript/code/routes/auth/app/ts/components/LoginComponent.ts
index 1255c30..56c700e 100644
--- a/manuscript/code/routes/auth/app/ts/components/LoginComponent.ts
+++ b/manuscript/code/routes/auth/app/ts/components/LoginComponent.ts
@@ -48,11 +48,9 @@ export class LoginComponent {
this.message = '';
if (!this.authService.login(username, password)) {
this.message = 'Incorrect credentials.';
- /* tslint:disable */
setTimeout(function() {
this.message = '';
}.bind(this), 2500);
- /* tslint:enable */
}
return false;
}
diff --git a/manuscript/code/routes/auth/app/ts/components/ProtectedComponent.ts b/manuscript/code/routes/auth/app/ts/components/ProtectedComponent.ts
index bed0ca2..16f26bd 100644
--- a/manuscript/code/routes/auth/app/ts/components/ProtectedComponent.ts
+++ b/manuscript/code/routes/auth/app/ts/components/ProtectedComponent.ts
@@ -1,24 +1,11 @@
/*
* Angular
*/
-import {Component, ReflectiveInjector} from '@angular/core';
-import {CanActivate} from '@angular/router-deprecated';
-
-/*
- * Services
- */
-import {AuthService} from 'services/AuthService';
+import {Component} from '@angular/core';
@Component({
selector: 'protected',
template: `<h1>Protected content</h1>`
})
-@CanActivate(
- (nextInstr: any, currInstr: any) => {
- let injector: any = ReflectiveInjector.resolveAndCreate([AuthService]);
- let authService: AuthService = injector.get(AuthService);
- return authService.isLogged();
- }
-)
export class ProtectedComponent {
}
diff --git a/manuscript/code/routes/auth/app/ts/guards/loggedIn.guard.ts b/manuscript/code/routes/auth/app/ts/guards/loggedIn.guard.ts
new file mode 100644
index 0000000..4f0b14a
--- /dev/null
+++ b/manuscript/code/routes/auth/app/ts/guards/loggedIn.guard.ts
@@ -0,0 +1,12 @@
+import { Injectable } from '@angular/core';
+import { CanActivate } from '@angular/router';
+import { AuthService } from 'services/AuthService';
+
+@Injectable()
+export class LoggedInGuard implements CanActivate {
+ constructor(private authService: AuthService) {}
+
+ canActivate(): boolean {
+ return this.authService.isLoggedIn();
+ }
+}
diff --git a/manuscript/code/routes/auth/app/ts/services/AuthService.ts b/manuscript/code/routes/auth/app/ts/services/AuthService.ts
index b38aaa5..27124cd 100644
--- a/manuscript/code/routes/auth/app/ts/services/AuthService.ts
+++ b/manuscript/code/routes/auth/app/ts/services/AuthService.ts
@@ -19,7 +19,7 @@ export class AuthService {
return localStorage.getItem('username');
}
- isLogged(): boolean {
+ isLoggedIn(): boolean {
return this.getUser() !== null;
}
}
diff --git a/manuscript/code/routes/auth/package.json b/manuscript/code/routes/auth/package.json
index cfb9d8d..13a4109 100644
--- a/manuscript/code/routes/auth/package.json
+++ b/manuscript/code/routes/auth/package.json
@@ -11,14 +11,14 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
- "@angular/router-deprecated": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"base64id": "0.1.0",
"core-js": "2.2.2",
"lodash": "3.10.1",
diff --git a/manuscript/code/routes/basic/app/ts/app.html5.ts b/manuscript/code/routes/basic/app/ts/app.html5.ts
index 5366df3..9ea7870 100644
--- a/manuscript/code/routes/basic/app/ts/app.html5.ts
+++ b/manuscript/code/routes/basic/app/ts/app.html5.ts
@@ -1,14 +1,13 @@
/*
* Angular
*/
-import {Component} from '@angular/core';
+import {provide, Component} from '@angular/core';
import {bootstrap} from '@angular/platform-browser-dynamic';
import {
ROUTER_DIRECTIVES,
- ROUTER_PROVIDERS,
- Router,
- RouteConfig,
-} from '@angular/router-deprecated';
+ provideRouter,
+ RouterConfig,
+} from '@angular/router';
/*
* Components
@@ -40,18 +39,17 @@ require('css/styles.scss');
</div>
`
})
-@RouteConfig([
- { path: '/', name: 'root', redirectTo: ['/Home'] },
- { path: '/home', name: 'Home', component: HomeComponent },
- { path: '/about', name: 'About', component: AboutComponent },
- { path: '/contact', name: 'Contact', component: ContactComponent },
- { path: '/contactus', name: 'ContactUs', redirectTo: ['/Contact'] },
-])
class RoutesDemoApp {
- constructor(public router: Router) {
- }
}
+const routes: RouterConfig = [
+ { path: '', redirectTo: 'home', terminal: true },
+ { path: 'home', component: HomeComponent },
+ { path: 'about', component: AboutComponent },
+ { path: 'contact', component: ContactComponent },
+ { path: 'contactus', redirectTo: 'contact' },
+];
+
bootstrap(RoutesDemoApp, [
- ROUTER_PROVIDERS,
+ provideRouter(routes)
]);
diff --git a/manuscript/code/routes/basic/app/ts/app.ts b/manuscript/code/routes/basic/app/ts/app.ts
index 862cec5..4536456 100644
--- a/manuscript/code/routes/basic/app/ts/app.ts
+++ b/manuscript/code/routes/basic/app/ts/app.ts
@@ -1,15 +1,13 @@
/*
- * Angular
+ * Angular Imports
*/
-
import {provide, Component} from '@angular/core';
import {bootstrap} from '@angular/platform-browser-dynamic';
import {
ROUTER_DIRECTIVES,
- ROUTER_PROVIDERS,
- RouteConfig,
-} from '@angular/router-deprecated';
-
+ provideRouter,
+ RouterConfig,
+} from '@angular/router';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
/*
@@ -32,9 +30,9 @@ require('css/styles.scss');
<nav>
<a>Navigation:</a>
<ul>
- <li><a [routerLink]="['/Home']">Home</a></li>
- <li><a [routerLink]="['/About']">About</a></li>
- <li><a [routerLink]="['/Contact']">Contact us</a></li>
+ <li><a [routerLink]="['home']">Home</a></li>
+ <li><a [routerLink]="['about']">About</a></li>
+ <li><a [routerLink]="['contact']">Contact us</a></li>
</ul>
</nav>
@@ -42,17 +40,18 @@ require('css/styles.scss');
</div>
`
})
-@RouteConfig([
- { path: '/', name: 'root', redirectTo: ['/Home'] },
- { path: '/home', name: 'Home', component: HomeComponent },
- { path: '/about', name: 'About', component: AboutComponent },
- { path: '/contact', name: 'Contact', component: ContactComponent },
- { path: '/contactus', name: 'ContactUs', redirectTo: ['/Contact'] },
-])
class RoutesDemoApp {
}
+const routes: RouterConfig = [
+ { path: '', redirectTo: 'home', terminal: true },
+ { path: 'home', component: HomeComponent },
+ { path: 'about', component: AboutComponent },
+ { path: 'contact', component: ContactComponent },
+ { path: 'contactus', redirectTo: 'contact' },
+];
+
bootstrap(RoutesDemoApp, [
- ROUTER_PROVIDERS,
+ provideRouter(routes), // <-- installs our routes
provide(LocationStrategy, {useClass: HashLocationStrategy})
]);
diff --git a/manuscript/code/routes/basic/package.json b/manuscript/code/routes/basic/package.json
index 103b7f6..aa1fdcc 100644
--- a/manuscript/code/routes/basic/package.json
+++ b/manuscript/code/routes/basic/package.json
@@ -10,13 +10,14 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"bootstrap-sass": "3.3.5",
@@ -41,7 +42,7 @@
"ts-helpers": "1.1.1",
"tslint": "3.7.0-dev.2",
"typescript": "1.9.0-dev.20160409",
- "typings": "0.8.1",
+ "typings": "1.3.0",
"url-loader": "0.5.6",
"uuid": "2.0.1",
"val-loader": "0.5.0",
diff --git a/manuscript/code/routes/basic/tsconfig.json b/manuscript/code/routes/basic/tsconfig.json
index 88e8d4a..74d48c7 100644
--- a/manuscript/code/routes/basic/tsconfig.json
+++ b/manuscript/code/routes/basic/tsconfig.json
@@ -21,6 +21,6 @@
"node_modules"
],
"atom": {
- "rewriteTsconfig": true
+ "rewriteTsconfig": false
}
}
diff --git a/manuscript/code/routes/basic/tslint.json b/manuscript/code/routes/basic/tslint.json
index ae663cb..23bf2f3 100644
--- a/manuscript/code/routes/basic/tslint.json
+++ b/manuscript/code/routes/basic/tslint.json
@@ -39,7 +39,6 @@
"no-shadowed-variable": true,
"no-string-literal": true,
"no-switch-case-fall-through": true,
- "no-trailing-comma": true,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-unused-variable": true,
@@ -55,7 +54,6 @@
"quotemark": [true, "single"],
"radix": true,
"semicolon": true,
- "sort-object-literal-keys": false,
"triple-equals": [true, "allow-null-check"],
"typedef": [true,
"call-signature",
diff --git a/manuscript/code/routes/basic/typings/index.d.ts b/manuscript/code/routes/basic/typings/index.d.ts
new file mode 100644
index 0000000..e69de29
diff --git a/manuscript/code/routes/music/app/ts/app.ts b/manuscript/code/routes/music/app/ts/app.ts
index 6b31c6b..68d06bc 100644
--- a/manuscript/code/routes/music/app/ts/app.ts
+++ b/manuscript/code/routes/music/app/ts/app.ts
@@ -1,5 +1,5 @@
/*
- * Angular
+ * Angular Imports
*/
import {
Component,
@@ -8,15 +8,15 @@ import {
import {bootstrap} from '@angular/platform-browser-dynamic';
import {HTTP_PROVIDERS} from '@angular/http';
import {
-
ROUTER_DIRECTIVES,
- ROUTER_PROVIDERS,
- ROUTER_PRIMARY_COMPONENT,
-
- Router,
- RouteConfig,
-} from '@angular/router-deprecated';
-import {LocationStrategy, HashLocationStrategy, APP_BASE_HREF} from '@angular/common';
+ provideRouter,
+ RouterConfig
+} from '@angular/router';
+import {
+ LocationStrategy,
+ HashLocationStrategy,
+ APP_BASE_HREF
+} from '@angular/common';
/*
* Components
@@ -30,6 +30,7 @@ import {AlbumComponent} from 'components/AlbumComponent';
* Services
*/
import {SPOTIFY_PROVIDERS} from 'services/SpotifyService';
+import {provideForms} from '@angular/forms';
/*
* Webpack
@@ -43,25 +44,25 @@ require('css/styles.scss');
<router-outlet></router-outlet>
`
})
-@RouteConfig([
- { path: '/', name: 'root', redirectTo: ['Search'] },
- { path: '/search', name: 'Search', component: SearchComponent },
- { path: '/artists/:id', name: 'Artists', component: ArtistComponent },
- { path: '/tracks/:id', name: 'Tracks', component: TrackComponent },
- { path: '/albums/:id', name: 'Albums', component: AlbumComponent },
-])
class RoutesDemoApp {
query: string;
-
- constructor(public router: Router) {
- }
}
+const routes: RouterConfig = [
+ { path: '', redirectTo: 'search', terminal: true },
+ { path: 'search', component: SearchComponent },
+ { path: 'artists/:id', component: ArtistComponent },
+ { path: 'tracks/:id', component: TrackComponent },
+ { path: 'albums/:id', component: AlbumComponent },
+];
+
+const ROUTER_PROVIDER = provideRouter(routes);
+
bootstrap(RoutesDemoApp, [
- ROUTER_PROVIDERS,
+ ROUTER_PROVIDER,
HTTP_PROVIDERS,
SPOTIFY_PROVIDERS,
- provide(ROUTER_PRIMARY_COMPONENT, {useValue: RoutesDemoApp}),
provide(APP_BASE_HREF, {useValue: '/'}),
- provide(LocationStrategy, {useClass: HashLocationStrategy})
+ provide(LocationStrategy, {useClass: HashLocationStrategy}),
+ provideForms()
]).catch((err: any) => console.error(err));
diff --git a/manuscript/code/routes/music/app/ts/components/AlbumComponent.ts b/manuscript/code/routes/music/app/ts/components/AlbumComponent.ts
index ae3a302..80a512d 100644
--- a/manuscript/code/routes/music/app/ts/components/AlbumComponent.ts
+++ b/manuscript/code/routes/music/app/ts/components/AlbumComponent.ts
@@ -3,8 +3,8 @@
*/
import {Component, OnInit} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';
-import {RouteParams, RouterLink} from '@angular/router-deprecated';
-import {LocationStrategy} from '@angular/common';
+import {ActivatedRoute, ROUTER_DIRECTIVES} from '@angular/router';
+import {Location} from '@angular/common';
/*
* Services
@@ -13,7 +13,7 @@ import {SpotifyService} from 'services/SpotifyService';
@Component({
selector: 'album',
- directives: [RouterLink, CORE_DIRECTIVES],
+ directives: [ROUTER_DIRECTIVES, CORE_DIRECTIVES],
template: `
<div *ngIf="album">
<h1>{{ album.name }}</h1>
@@ -26,7 +26,7 @@ import {SpotifyService} from 'services/SpotifyService';
<h3>Tracks</h3>
<ol>
<li *ngFor="let t of album.tracks.items">
- <a [routerLink]="['/Tracks', {id: t.id}]">
+ <a [routerLink]="['/tracks', t.id]">
{{ t.name }}
</a>
</li>
@@ -40,9 +40,9 @@ export class AlbumComponent implements OnInit {
id: string;
album: Object;
- constructor(public routeParams: RouteParams, public spotify: SpotifyService,
- public locationStrategy: LocationStrategy) {
- this.id = routeParams.get('id');
+ constructor(public route: ActivatedRoute, public spotify: SpotifyService,
+ public location: Location) {
+ route.params.subscribe(params => { this.id = params['id']; });
}
ngOnInit(): void {
@@ -52,7 +52,7 @@ export class AlbumComponent implements OnInit {
}
back(): void {
- this.locationStrategy.back();
+ this.location.back();
}
renderAlbum(res: any): void {
diff --git a/manuscript/code/routes/music/app/ts/components/ArtistComponent.ts b/manuscript/code/routes/music/app/ts/components/ArtistComponent.ts
index ff8f897..8912b44 100644
--- a/manuscript/code/routes/music/app/ts/components/ArtistComponent.ts
+++ b/manuscript/code/routes/music/app/ts/components/ArtistComponent.ts
@@ -3,8 +3,8 @@
*/
import {Component, OnInit} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';
-import {RouteParams} from '@angular/router-deprecated';
-import {LocationStrategy} from '@angular/common';
+import {ActivatedRoute} from '@angular/router';
+import {Location} from '@angular/common';
/*
* Services
@@ -30,9 +30,9 @@ export class ArtistComponent implements OnInit {
id: string;
artist: Object;
- constructor(public routeParams: RouteParams, public spotify: SpotifyService,
- public locationStrategy: LocationStrategy) {
- this.id = routeParams.get('id');
+ constructor(public route: ActivatedRoute, public spotify: SpotifyService,
+ public location: Location) {
+ route.params.subscribe(params => { this.id = params['id']; });
}
ngOnInit(): void {
@@ -42,7 +42,7 @@ export class ArtistComponent implements OnInit {
}
back(): void {
- this.locationStrategy.back();
+ this.location.back();
}
renderArtist(res: any): void {
diff --git a/manuscript/code/routes/music/app/ts/components/SearchComponent.ts b/manuscript/code/routes/music/app/ts/components/SearchComponent.ts
index dd4b572..c55e64e 100644
--- a/manuscript/code/routes/music/app/ts/components/SearchComponent.ts
+++ b/manuscript/code/routes/music/app/ts/components/SearchComponent.ts
@@ -6,9 +6,9 @@ import {Component, OnInit} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';
import {
Router,
- RouterLink,
- RouteParams,
-} from '@angular/router-deprecated';
+ ROUTER_DIRECTIVES,
+ ActivatedRoute,
+} from '@angular/router';
/*
* Services
@@ -17,7 +17,7 @@ import {SpotifyService} from 'services/SpotifyService';
@Component({
selector: 'search',
- directives: [RouterLink, CORE_DIRECTIVES],
+ directives: [ROUTER_DIRECTIVES, CORE_DIRECTIVES],
template: `
<h1>Search</h1>
@@ -43,20 +43,20 @@ import {SpotifyService} from 'services/SpotifyService';
<img src="{{ t.album.images[0].url }}" class="img-responsive">
<div class="caption">
<h3>
- <a [routerLink]="['/Artists', {id: t.artists[0].id}]">
+ <a [routerLink]="['/artists', t.artists[0].id]">
{{ t.artists[0].name }}
</a>
</h3>
<br>
<p>
- <a [routerLink]="['/Tracks', {id: t.id}]">
+ <a [routerLink]="['/tracks', t.id]">
{{ t.name }}
</a>
</p>
</div>
<div class="attribution">
<h4>
- <a [routerLink]="['/Albums', {id: t.album.id}]">
+ <a [routerLink]="['/albums', t.album.id]">
{{ t.album.name }}
</a>
</h4>
@@ -73,8 +73,10 @@ export class SearchComponent implements OnInit {
query: string;
results: Object;
- constructor(public spotify: SpotifyService, public router: Router,
- public routeParams: RouteParams) {
+ constructor(private spotify: SpotifyService, private router: Router,
+ private route: ActivatedRoute) {
+ router.routerState.queryParams
+ .subscribe(params => { this.query = params['query'] || ''; });
}
ngOnInit(): void {
@@ -82,12 +84,11 @@ export class SearchComponent implements OnInit {
}
submit(query: string): void {
- this.router.navigate(['/Search', {query: query}]);
- this.search();
+ this.router.navigate(['search'], { queryParams: { query: query } })
+ .then(_ => this.search() );
}
search(): void {
- this.query = this.routeParams.get('query');
if (!this.query) {
return;
}
diff --git a/manuscript/code/routes/music/app/ts/components/TrackComponent.ts b/manuscript/code/routes/music/app/ts/components/TrackComponent.ts
index 43690e6..0d48197 100644
--- a/manuscript/code/routes/music/app/ts/components/TrackComponent.ts
+++ b/manuscript/code/routes/music/app/ts/components/TrackComponent.ts
@@ -4,8 +4,8 @@
import {Component, OnInit} from '@angular/core';
import {CORE_DIRECTIVES} from '@angular/common';
-import {RouteParams} from '@angular/router-deprecated';
-import {LocationStrategy} from '@angular/common';
+import {ActivatedRoute} from '@angular/router';
+import {Location} from '@angular/common';
/*
* Services
@@ -39,9 +39,9 @@ export class TrackComponent implements OnInit {
id: string;
track: Object;
- constructor(public routeParams: RouteParams, public spotify: SpotifyService,
- public locationStrategy: LocationStrategy) {
- this.id = routeParams.get('id');
+ constructor(public route: ActivatedRoute, public spotify: SpotifyService,
+ public location: Location) {
+ route.params.subscribe(params => { this.id = params['id']; });
}
ngOnInit(): void {
@@ -51,7 +51,7 @@ export class TrackComponent implements OnInit {
}
back(): void {
- this.locationStrategy.back();
+ this.location.back();
}
renderTrack(res: any): void {
diff --git a/manuscript/code/routes/music/app/ts/vendor.ts b/manuscript/code/routes/music/app/ts/vendor.ts
index 9fdc3a7..926724b 100644
--- a/manuscript/code/routes/music/app/ts/vendor.ts
+++ b/manuscript/code/routes/music/app/ts/vendor.ts
@@ -10,7 +10,7 @@ import 'zone.js/dist/long-stack-trace-zone';
import '@angular/platform-browser-dynamic';
import '@angular/common';
import '@angular/core';
-import '@angular/router-deprecated';
+import '@angular/router';
import '@angular/http';
// RxJS
diff --git a/manuscript/code/routes/music/karma.conf.js b/manuscript/code/routes/music/karma.conf.js
index aeaef77..fb1058c 100644
--- a/manuscript/code/routes/music/karma.conf.js
+++ b/manuscript/code/routes/music/karma.conf.js
@@ -23,10 +23,11 @@ module.exports = function(config) {
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
- 'test.bundle.js': ['webpack']
+ 'test.bundle.js': ['webpack', 'sourcemap']
},
webpack: {
+ devtool: 'inline-source-map',
resolve: {
root: [path.resolve(cwd)],
modulesDirectories: ['node_modules', 'app', 'app/ts', 'test', '.'],
diff --git a/manuscript/code/routes/music/package.json b/manuscript/code/routes/music/package.json
index 1321d20..aceab89 100644
--- a/manuscript/code/routes/music/package.json
+++ b/manuscript/code/routes/music/package.json
@@ -6,19 +6,19 @@
"scripts": {
"go": "./node_modules/.bin/webpack-dev-server",
"clean": "true",
- "test": "karma start"
+ "test": "karma start --single-run"
},
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
- "@angular/router-deprecated": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"base64id": "0.1.0",
"core-js": "2.2.2",
"lodash": "3.10.1",
diff --git a/manuscript/code/routes/music/test/MusicTestHelpers.ts b/manuscript/code/routes/music/test/MusicTestHelpers.ts
new file mode 100644
index 0000000..5c6f399
--- /dev/null
+++ b/manuscript/code/routes/music/test/MusicTestHelpers.ts
@@ -0,0 +1,105 @@
+import {
+ Component,
+ ComponentResolver,
+ Injector
+} from '@angular/core';
+import { tick } from '@angular/core/testing';
+import { TestComponentBuilder, ComponentFixture } from '@angular/core/testing';
+import { BrowserPlatformLocation } from '@angular/platform-browser';
+import {
+ ROUTER_DIRECTIVES,
+ ActivatedRoute,
+ Router,
+ RouterConfig,
+ RouterOutletMap,
+ DefaultUrlSerializer,
+ UrlSerializer
+} from '@angular/router';
+import {
+ PlatformLocation,
+ Location,
+ LocationStrategy,
+ HashLocationStrategy
+} from '@angular/common';
+import { SpyLocation } from '@angular/common/testing';
+import { AlbumComponent } from '../app/ts/components/AlbumComponent';
+import { ArtistComponent } from '../app/ts/components/ArtistComponent';
+import { SearchComponent } from '../app/ts/components/SearchComponent';
+import { TrackComponent } from '../app/ts/components/TrackComponent';
+import { MockSpotifyService } from './mocks/spotify';
+
+export function advance(fixture: ComponentFixture<any>): void {
+ tick();
+ fixture.detectChanges();
+}
+
+@Component({
+ selector: 'blank-cmp',
+ template: ``,
+ directives: [ROUTER_DIRECTIVES]
+})
+export class BlankCmp {
+}
+
+@Component({
+ selector: 'root-cmp',
+ template: `<router-outlet></router-outlet>`,
+ directives: [ROUTER_DIRECTIVES],
+ precompile: [BlankCmp, SearchComponent, ArtistComponent,
+ TrackComponent, AlbumComponent]
+})
+export class RootCmp {
+}
+
+export function createRoot(tcb: TestComponentBuilder,
+ router: Router,
+ type: any): ComponentFixture<any> {
+ const f = tcb.createFakeAsync(type);
+ advance(f);
+ (<any>router).initialNavigation();
+ advance(f);
+ return f;
+}
+
+export const routerConfig: RouterConfig = [
+ { path: '', component: BlankCmp },
+ { path: 'search', component: SearchComponent },
+ { path: 'artists/:id', component: ArtistComponent },
+ { path: 'tracks/:id', component: TrackComponent },
+ { path: 'albums/:id', component: AlbumComponent }
+];
+
+export function musicTestProviders() {
+ const mockSpotifyService: MockSpotifyService = new MockSpotifyService();
+
+ return [
+ RouterOutletMap,
+ {provide: UrlSerializer, useClass: DefaultUrlSerializer},
+ {provide: Location, useClass: SpyLocation},
+ {provide: LocationStrategy, useClass: HashLocationStrategy},
+ {provide: PlatformLocation, useClass: BrowserPlatformLocation},
+ {
+ provide: Router,
+ useFactory: (resolver: ComponentResolver, urlSerializer: UrlSerializer,
+ outletMap: RouterOutletMap, location: Location,
+ injector: Injector) => {
+ return new Router(
+ RootCmp, resolver, urlSerializer, outletMap,
+ location, injector, routerConfig);
+ },
+ deps: [
+ ComponentResolver,
+ UrlSerializer,
+ RouterOutletMap,
+ Location,
+ Injector
+ ]
+ },
+ {
+ provide: ActivatedRoute,
+ useFactory: (r: Router) => r.routerState.root, deps: [Router]
+ },
+ mockSpotifyService.getProviders(),
+ ];
+};
+
diff --git a/manuscript/code/routes/music/test/components/AlbumComponent.spec.ts b/manuscript/code/routes/music/test/components/AlbumComponent.spec.ts
index 1d15f01..dc6f03a 100644
--- a/manuscript/code/routes/music/test/components/AlbumComponent.spec.ts
+++ b/manuscript/code/routes/music/test/components/AlbumComponent.spec.ts
@@ -1,61 +1,67 @@
import {
it,
describe,
- fdescribe,
- expect,
inject,
- injectAsync,
- afterEach,
- beforeEachProviders,
+ fakeAsync,
+ addProviders
} from '@angular/core/testing';
-import {TestComponentBuilder} from '@angular/compiler/testing';
-
-import {MockRouterProvider} from '../mocks/routes';
-import {MockSpotifyService} from '../mocks/spotify';
-
-import {AlbumComponent} from '../../app/ts/components/AlbumComponent';
+import { Router } from '@angular/router';
+import { Location } from '@angular/common';
+import { TestComponentBuilder } from '@angular/core/testing';
+import { MockSpotifyService } from '../mocks/spotify';
+import { SpotifyService } from '../../app/ts/services/SpotifyService';
+import {
+ musicTestProviders,
+ advance,
+ createRoot,
+ RootCmp
+} from '../MusicTestHelpers';
describe('AlbumComponent', () => {
- var mockSpotifyService: MockSpotifyService;
- var mockRouterProvider: MockRouterProvider;
-
- beforeEachProviders(() => {
- mockSpotifyService = new MockSpotifyService();
- mockRouterProvider = new MockRouterProvider();
-
- return [
- mockSpotifyService.getProviders(), mockRouterProvider.getProviders()
- ];
+ beforeEach(() => {
+ addProviders(musicTestProviders());
});
describe('initialization', () => {
- it('retrieves the album', injectAsync([TestComponentBuilder], (tcb) => {
- // makes the RouteParams return 1 as the album id
- mockRouterProvider.setRouteParam('id', 1);
-
- return tcb.createAsync(AlbumComponent).then((fixture) => {
- fixture.detectChanges();
- expect(mockSpotifyService.getAlbumSpy).toHaveBeenCalledWith(1);
- });
- }));
+ it('retrieves the album', fakeAsync(
+ inject([Router, TestComponentBuilder, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ mockSpotifyService: MockSpotifyService) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+
+ router.navigateByUrl('/albums/1');
+ advance(fixture);
+
+ expect(mockSpotifyService.getAlbumSpy).toHaveBeenCalledWith('1');
+ })));
});
describe('back', () => {
- it('returns to the previous location', injectAsync([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(AlbumComponent).then((fixture) => {
- let albumComponent = fixture.debugElement.componentInstance;
- let backSpy = mockRouterProvider.mockLocationStrategy.spy('back');
-
- albumComponent.back();
- expect(backSpy).toHaveBeenCalled();
- });
- }));
+ it('returns to the previous location', fakeAsync(
+ inject([Router, TestComponentBuilder, Location],
+ (router: Router, tcb: TestComponentBuilder, location: Location) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ expect(location.path()).toEqual('/');
+
+ router.navigateByUrl('/albums/1');
+ advance(fixture);
+ expect(location.path()).toEqual('/albums/1');
+
+ const album = fixture.debugElement.children[1].componentInstance;
+ album.back();
+ advance(fixture);
+
+ expect(location.path()).toEqual('/');
+ })));
});
describe('renderAlbum', () => {
- it('renders album info', injectAsync([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(AlbumComponent).then((fixture) => {
- let albumComponent = fixture.debugElement.componentInstance;
+ it('renders album info', fakeAsync(
+ inject([Router, TestComponentBuilder, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ mockSpotifyService: MockSpotifyService) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+
let album = {
name: 'ALBUM NAME',
artists: [{name: 'ARTIST NAME'}],
@@ -64,18 +70,21 @@ describe('AlbumComponent', () => {
items: [{id: 1, name: 'TRACK 1'},{id: 2, name: 'TRACK 2'}]
}
};
-
mockSpotifyService.setResponse(album);
- fixture.detectChanges();
- var compiled = fixture.debugElement.nativeElement;
- expect(compiled.querySelector('h1')).toHaveText('ALBUM NAME');
- expect(compiled.querySelector('h2')).toHaveText('ARTIST NAME');
+ router.navigateByUrl('/albums/1');
+ advance(fixture);
+
+ const compiled = fixture.debugElement.nativeElement;
+
+ expect(compiled.querySelector('h1').innerHTML).toContain('ALBUM NAME');
+ expect(compiled.querySelector('h2').innerHTML).toContain('ARTIST NAME');
var links = compiled.querySelectorAll('a');
expect(links[0].innerText).toContain('TRACK 1');
expect(links[1].innerText).toContain('TRACK 2');
- });
- }));
+ })));
});
});
+
+
diff --git a/manuscript/code/routes/music/test/components/ArtistComponent.spec.ts b/manuscript/code/routes/music/test/components/ArtistComponent.spec.ts
index 620d3c7..64b39ca 100644
--- a/manuscript/code/routes/music/test/components/ArtistComponent.spec.ts
+++ b/manuscript/code/routes/music/test/components/ArtistComponent.spec.ts
@@ -1,70 +1,78 @@
import {
it,
describe,
- expect,
inject,
- async,
- afterEach,
- beforeEachProviders,
+ fakeAsync,
+ addProviders
} from '@angular/core/testing';
-import {TestComponentBuilder} from '@angular/compiler/testing';
-
-import {MockRouterProvider} from "../mocks/routes";
-import {MockSpotifyService} from "../mocks/spotify";
-import {TestHelper} from "../mocks/helper";
+import { Router } from '@angular/router';
+import { Location } from '@angular/common';
+import { TestComponentBuilder } from '@angular/compiler/testing';
+import { MockSpotifyService } from '../mocks/spotify';
+import { SpotifyService } from '../../app/ts/services/SpotifyService';
+import {
+ musicTestProviders,
+ advance,
+ createRoot,
+ RootCmp
+} from '../MusicTestHelpers';
-import {ArtistComponent} from "../../app/ts/components/ArtistComponent";
+describe('ArtistComponent', () => {
+ beforeEach(() => {
+ addProviders(musicTestProviders());
+ });
-describe("ArtistComponent", () => {
- var mockSpotifyService: MockSpotifyService;
- var mockRouterProvider: MockRouterProvider;
+ describe('initialization', () => {
+ it('retrieves the artist', fakeAsync(
+ inject([Router, SpotifyService, TestComponentBuilder],
+ (router: Router,
+ mockSpotifyService: MockSpotifyService,
+ tcb: TestComponentBuilder) => {
+ const fixture = createRoot(tcb, router, RootCmp);
- beforeEachProviders(() => {
- mockSpotifyService = new MockSpotifyService();
- mockRouterProvider = new MockRouterProvider();
+ router.navigateByUrl('/artists/2');
+ advance(fixture);
- return [
- mockSpotifyService.getProviders(), mockRouterProvider.getProviders()
- ];
+ expect(mockSpotifyService.getArtistSpy).toHaveBeenCalledWith('2');
+ })));
});
- describe("initialization", () => {
- it("retrieves the artist", async(inject([TestComponentBuilder], (tcb) => {
- // makes the RouteParams return 2 as the artist id
- mockRouterProvider.setRouteParam('id', 2);
+ describe('back', () => {
+ it('returns to the previous location', fakeAsync(
+ inject([Router, TestComponentBuilder, Location],
+ (router: Router, tcb: TestComponentBuilder, location: Location) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ expect(location.path()).toEqual('/');
- return tcb.createAsync(ArtistComponent).then((fixture) => {
- fixture.detectChanges();
- expect(mockSpotifyService.getArtistSpy).toHaveBeenCalledWith(2);
- });
- })));
- });
+ router.navigateByUrl('/artists/2');
+ advance(fixture);
+ expect(location.path()).toEqual('/artists/2');
- describe('back', () => {
- it('returns to the previous location', async(inject([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(ArtistComponent).then((fixture) => {
- let artistComponent = fixture.debugElement.componentInstance;
- let backSpy = mockRouterProvider.mockLocationStrategy.spy('back');
+ const artist = fixture.debugElement.children[1].componentInstance;
+ artist.back();
+ advance(fixture);
- artistComponent.back();
- expect(backSpy).toHaveBeenCalled();
- });
- })));
+ expect(location.path()).toEqual('/');
+ })));
});
describe('renderArtist', () => {
- it('renders artist info', async(inject([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(ArtistComponent).then((fixture) => {
- let artistComponent = fixture.debugElement.componentInstance;
- let artist = {name: 'ARTIST NAME', images: [{url: 'IMAGE_1'}]};
+ it('renders album info', fakeAsync(
+ inject([Router, TestComponentBuilder, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ mockSpotifyService: MockSpotifyService) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ let artist = {name: 'ARTIST NAME', images: [{url: 'IMAGE_1'}]};
mockSpotifyService.setResponse(artist);
- fixture.detectChanges();
- var compiled = fixture.debugElement.nativeElement;
- expect(compiled.querySelector('h1')).toHaveText('ARTIST NAME');
+ router.navigateByUrl('/artists/2');
+ advance(fixture);
+
+ const compiled = fixture.debugElement.nativeElement;
+
+ expect(compiled.querySelector('h1').innerHTML).toContain('ARTIST NAME');
expect(compiled.querySelector('img').src).toContain('IMAGE_1');
- });
- })));
+ })));
});
});
diff --git a/manuscript/code/routes/music/test/components/SearchComponent.spec.ts b/manuscript/code/routes/music/test/components/SearchComponent.spec.ts
index 314a853..32240af 100644
--- a/manuscript/code/routes/music/test/components/SearchComponent.spec.ts
+++ b/manuscript/code/routes/music/test/components/SearchComponent.spec.ts
@@ -1,165 +1,124 @@
import {
it,
- fdescribe,
describe,
- expect,
inject,
- async,
- afterEach,
- beforeEachProviders,
+ fakeAsync,
+ addProviders
} from '@angular/core/testing';
-import {TestComponentBuilder} from '@angular/compiler/testing';
-import {Router} from "@angular/router-deprecated";
-import {DebugElement} from '@angular/core/src/debug/debug_node';
-
-import {MockRouterProvider} from '../mocks/routes';
-import {MockSpotifyService} from '../mocks/spotify';
-import {TestHelper} from '../mocks/helper';
-
-import {SearchComponent} from '../../app/ts/components/SearchComponent';
+import { Router } from '@angular/router';
+import { Location } from '@angular/common';
+import { TestComponentBuilder } from '@angular/core/testing';
+import { MockSpotifyService } from '../mocks/spotify';
+import { SpotifyService } from '../../app/ts/services/SpotifyService';
+import {
+ musicTestProviders,
+ advance,
+ createRoot,
+ RootCmp
+} from '../MusicTestHelpers';
describe('SearchComponent', () => {
- var mockSpotifyService: MockSpotifyService;
- var mockRouterProvider: MockRouterProvider;
-
- beforeEachProviders(() => {
- mockSpotifyService = new MockSpotifyService();
- mockRouterProvider = new MockRouterProvider();
-
- return [
- mockSpotifyService.getProviders(), mockRouterProvider.getProviders()
- ];
+ beforeEach(() => {
+ addProviders(musicTestProviders());
});
describe('initialization', () => {
- it(`doesn\'t search for a track without a query`,
- async(inject([TestComponentBuilder], (tcb) => {
- var search = mockSpotifyService.spy('searchTrack');
- return tcb.createAsync(SearchComponent).then((fixture) => {
- fixture.detectChanges();
- expect(search).not.toHaveBeenCalled();
- });
- }))
- );
-
- it('searches for a track if a query is provided',
- async(inject([TestComponentBuilder], (tcb) => {
- var search = mockSpotifyService.spy('searchTrack');
- mockRouterProvider.setRouteParam('query', 'QUERY');
-
- return tcb.createAsync(SearchComponent).then((rootTC) => {
- rootTC.detectChanges();
- expect(search).toHaveBeenCalled();
- });
- }))
- );
- });
-
- describe('submit', () => {
- describe('testing the method', () => {
- it('navigates to the Search route',
- async(inject([TestComponentBuilder], (tcb) => {
- var navigate = mockRouterProvider.mockRouter.spy('navigate');
-
- return tcb.createAsync(SearchComponent).then((fixture) => {
- let searchComponent = fixture.debugElement.componentInstance;
- searchComponent.submit("QUERY");
- expect(navigate).toHaveBeenCalledWith(["/Search", {query: "QUERY"}]);
- });
- }))
- );
-
- it('performs the search',
- async(inject([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(SearchComponent).then((fixture) => {
- let searchComponent = fixture.debugElement.componentInstance;
- let search = spyOn(searchComponent, 'search');
-
- searchComponent.submit("QUERY");
- expect(search).toHaveBeenCalled();
- });
- }))
- );
- });
-
- describe('testing the interaction', () => {
- it('navigates to the Search route',
- async(inject([TestComponentBuilder], (tcb) => {
- let navigate = mockRouterProvider.mockRouter.spy('navigate');
-
- return tcb.createAsync(SearchComponent).then((fixture) => {
- var compiled = fixture.debugElement.nativeElement;
- var input = compiled.querySelector('input');
- var button = compiled.querySelector('button');
-
- fixture.detectChanges();
-
- // sets the value of the search field to "QUERY"
- // and clicks the search button
- input.value = "QUERY";
- button.click();
-
- expect(navigate).toHaveBeenCalledWith(["/Search", {query: "QUERY"}]);
- });
- }))
- );
- });
+ it(`doesn't search for a track without a query`, fakeAsync(
+ inject([Router, TestComponentBuilder, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ mockSpotifyService: MockSpotifyService) => {
+ const searchSpy = mockSpotifyService.spy('searchTrack');
+ const fixture = createRoot(tcb, router, RootCmp);
+ router.navigateByUrl('/search');
+ advance(fixture);
+ expect(searchSpy).not.toHaveBeenCalled();
+ })));
+
+ it(`searches for a track if a query is provided`, fakeAsync(
+ inject([Router, TestComponentBuilder, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ mockSpotifyService: MockSpotifyService) => {
+ const searchSpy = mockSpotifyService.spy('searchTrack');
+ const fixture = createRoot(tcb, router, RootCmp);
+ router.navigateByUrl('/search?query=cats');
+ advance(fixture);
+ expect(searchSpy).toHaveBeenCalled();
+ })));
});
- describe('search', () => {
- it('searches when a query is present',
- async(inject([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(SearchComponent).then((fixture) => {
- var searchComponent = fixture.debugElement.componentInstance;
- mockRouterProvider.setRouteParam('query', 'QUERY')
-
- searchComponent.search();
- expect(mockSpotifyService.searchTrackSpy).toHaveBeenCalledWith("QUERY")
- })
- }))
- );
-
- it(`doesn\'t search when a query is absent`,
- async(inject([TestComponentBuilder], (tcb) => {
- return tcb.createAsync(SearchComponent).then((fixture) => {
- var searchComponent = fixture.debugElement.componentInstance;
-
- searchComponent.search();
- expect(mockSpotifyService.searchTrackSpy).not.toHaveBeenCalled();
- });
- }))
- );
+ describe('submitting a search', () => {
+ it('navigates to the Search route', fakeAsync(
+ inject([Router, TestComponentBuilder, Location],
+ (router: Router, tcb: TestComponentBuilder, location: Location) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ expect(location.path()).toEqual('/');
+
+ router.navigateByUrl('/search');
+ advance(fixture);
+
+ const searchComponent = fixture.debugElement.children[1].componentInstance;
+ const searchSpy = spyOn(searchComponent, 'search');
+ searchComponent.submit('cats');
+ advance(fixture);
+
+ expect(location.path()).toEqual('/search?query=cats');
+ expect(searchSpy).toHaveBeenCalled();
+ })));
+
+ it('can search with a button', fakeAsync(
+ inject([Router, TestComponentBuilder, Location],
+ (router: Router, tcb: TestComponentBuilder, location: Location) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ router.navigateByUrl('/search');
+ advance(fixture);
+ expect(location.path()).toEqual('/search');
+
+ const compiled = fixture.debugElement.nativeElement;
+ const searchComponent = fixture.debugElement.children[1].componentInstance;
+ const searchSpy = spyOn(searchComponent, 'search');
+ const input = compiled.querySelector('input');
+ const button = compiled.querySelector('button');
+
+ input.value = 'cats';
+ button.click();
+ advance(fixture);
+
+ expect(location.path()).toEqual('/search?query=cats');
+ expect(searchSpy).toHaveBeenCalled();
+ })));
});
describe('renderResults', () => {
- it('display a message when no results are found',
- async(inject([Router, TestComponentBuilder], (router, tcb) => {
- return tcb.createAsync(SearchComponent).then((fixture) => {
- mockSpotifyService.setResponse({tracks: {items: []}});
- mockRouterProvider.setRouteParam('query', 'QUERY');
-
- var searchComponent = fixture.debugElement.componentInstance;
- var compiled = fixture.debugElement.nativeElement;
- var input = compiled.querySelector('input');
- var button = compiled.querySelector('button');
-
- fixture.detectChanges();
-
- // sets the value of the search field to "QUERY"
- // and clicks the search button
- input.value = "QUERY";
- button.click();
-
- expect(compiled.innerText)
- .toContain("No tracks were found with the term 'QUERY'");
- });
- }))
- );
-
- it('display results',
- async(inject([Router, TestComponentBuilder], (router, tcb) => {
- return tcb.createAsync(SearchComponent).then((fixture) => {
- var searchComponent = fixture.debugElement.componentInstance;
+ it('displays a message when no results are found', fakeAsync(
+ inject([Router, TestComponentBuilder, Location, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ location: Location, mockSpotifyService: MockSpotifyService) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ router.navigateByUrl('/search');
+ advance(fixture);
+
+ mockSpotifyService.setResponse({tracks: {items: []}});
+
+ const compiled = fixture.debugElement.nativeElement;
+ const input = compiled.querySelector('input');
+ const button = compiled.querySelector('button');
+
+ input.value = 'cats';
+ button.click();
+ advance(fixture);
+
+ expect(compiled.innerText)
+ .toContain(`No tracks were found with the term 'cats'`);
+ })));
+
+ it('displays results', fakeAsync(
+ inject([Router, TestComponentBuilder, Location, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ location: Location, mockSpotifyService: MockSpotifyService) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ router.navigateByUrl('/search');
+ advance(fixture);
+
var response = {
tracks: {
items: [
@@ -167,27 +126,26 @@ describe('SearchComponent', () => {
id: 1,
name: 'TRACK',
album: { id: 2, name: 'ALBUM', images: [{url: 'IMAGE_1'}] },
- artists: [ {id: 3, name: 'ARTIST'} ]
- }
- ]
- }
- };
-
- searchComponent.renderResults(response);
- fixture.detectChanges();
-
- // checks the album URL matches
- var compiled = fixture.debugElement.nativeElement;
- expect(compiled.querySelector('img').src).toContain('IMAGE_1');
-
- // checks the artist, track and album information
- var links = compiled.querySelectorAll('a');
- expect(links.length).toEqual(3);
- expect(links[0].innerText).toEqual('ARTIST');
- expect(links[1].innerText).toEqual('TRACK');
- expect(links[2].innerText).toEqual('ALBUM');
- })
- }))
- );
+ artists: [ {id: 3, name: 'ARTIST'} ]}]}};
+
+ mockSpotifyService.setResponse(response);
+
+ const compiled = fixture.debugElement.nativeElement;
+ const input = compiled.querySelector('input');
+ const button = compiled.querySelector('button');
+
+ input.value = 'cats';
+ button.click();
+ advance(fixture);
+
+ expect(compiled.querySelector('img').src).toContain('IMAGE_1');
+
+ // checks the artist, track and album information
+ var links = compiled.querySelectorAll('a');
+ expect(links.length).toEqual(3);
+ expect(links[0].innerText).toEqual('ARTIST');
+ expect(links[1].innerText).toEqual('TRACK');
+ expect(links[2].innerText).toEqual('ALBUM');
+ })));
});
});
diff --git a/manuscript/code/routes/music/test/components/TrackComponent.spec.ts b/manuscript/code/routes/music/test/components/TrackComponent.spec.ts
index 4767890..012521c 100644
--- a/manuscript/code/routes/music/test/components/TrackComponent.spec.ts
+++ b/manuscript/code/routes/music/test/components/TrackComponent.spec.ts
@@ -3,75 +3,78 @@ import {
describe,
expect,
inject,
- injectAsync,
- afterEach,
- beforeEachProviders,
+ fakeAsync,
+ addProviders
} from '@angular/core/testing';
-import { TestComponentBuilder } from '@angular/compiler/testing';
-
-import {MockRouterProvider} from "../mocks/routes";
-import {MockSpotifyService} from "../mocks/spotify";
-import {TestHelper} from "../mocks/helper";
-
-import {TrackComponent} from "../../app/ts/components/TrackComponent";
-
-let mockSpotifyService: MockSpotifyService = new MockSpotifyService();
-let mockRouterProvider: MockRouterProvider = new MockRouterProvider();
+import { Router } from '@angular/router';
+import { Location } from '@angular/common';
+import { TestComponentBuilder } from '@angular/core/testing';
+import { MockSpotifyService } from '../mocks/spotify';
+import { SpotifyService } from '../../app/ts/services/SpotifyService';
+import {
+ musicTestProviders,
+ advance,
+ createRoot,
+ RootCmp
+} from '../MusicTestHelpers';
describe("TrackComponent", () => {
- var mockSpotifyService: MockSpotifyService;
- var mockRouterProvider: MockRouterProvider;
- var template = `<h1 *ngIf="track">{{track.name}}</h1>`;
-
- beforeEachProviders(() => {
- mockSpotifyService = new MockSpotifyService();
- mockRouterProvider = new MockRouterProvider();
-
- return [
- mockSpotifyService.getProviders(), mockRouterProvider.getProviders()
- ];
+ beforeEach(() => {
+ addProviders(musicTestProviders());
});
- describe("initialization", () => {
- it("retrieves the track", injectAsync([TestComponentBuilder], (tcb) => {
- // makes the RouteParams return 1 as the track id
- mockRouterProvider.setRouteParam('id', 1);
+ describe('initialization', () => {
+ it('retrieves the track', fakeAsync(
+ inject([Router, TestComponentBuilder, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ mockSpotifyService: MockSpotifyService) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ advance(fixture);
- return tcb.overrideTemplate(TrackComponent, template)
- .createAsync(TrackComponent).then((fixture) => {
- fixture.detectChanges();
- expect(mockSpotifyService.getTrackSpy).toHaveBeenCalledWith(1);
- });
- }));
+ router.navigateByUrl('/tracks/1');
+ advance(fixture);
+
+ expect(mockSpotifyService.getTrackSpy).toHaveBeenCalledWith('1');
+ })));
});
+
describe('back', () => {
- it('returns to the previous location',
- injectAsync([TestComponentBuilder], (tcb) => {
- return tcb.overrideTemplate(TrackComponent, template)
- .createAsync(TrackComponent).then((fixture) => {
- var trackComponent = fixture.debugElement.componentInstance;
- var backSpy = mockRouterProvider.mockLocationStrategy.spy('back');
+ it('returns to the previous location', fakeAsync(
+ inject([Router, TestComponentBuilder, Location],
+ (router: Router, tcb: TestComponentBuilder, location: Location) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+ expect(location.path()).toEqual('/');
+
+ router.navigateByUrl('/tracks/1');
+ advance(fixture);
+ expect(location.path()).toEqual('/tracks/1');
- trackComponent.back();
- expect(backSpy).toHaveBeenCalled();
- });
- })
- );
+ const album = fixture.debugElement.children[1].componentInstance;
+ album.back();
+ advance(fixture);
+
+ expect(location.path()).toEqual('/');
+ })));
});
describe('renderTrack', () => {
- it('renders track info', injectAsync([TestComponentBuilder], (tcb) => {
- return tcb.overrideTemplate(TrackComponent, template)
- .createAsync(TrackComponent).then((fixture) => {
- var trackComponent = fixture.debugElement.componentInstance;
- mockSpotifyService.setResponse({name: 'TRACK NAME'});
+ it('renders track info', fakeAsync(
+ inject([Router, TestComponentBuilder, SpotifyService],
+ (router: Router, tcb: TestComponentBuilder,
+ mockSpotifyService: MockSpotifyService) => {
+ const fixture = createRoot(tcb, router, RootCmp);
+
+ let response = {
+ name: 'TRACK NAME',
+ album: { images: [{url: 'IMAGE_0.png'}, {url: 'IMAGE_1.png'}] } };
+ mockSpotifyService.setResponse(response);
- fixture.detectChanges();
+ router.navigateByUrl('/tracks/1');
+ advance(fixture);
- var compiled = fixture.debugElement.nativeElement;
- expect(compiled.querySelector('h1')).toHaveText('TRACK NAME');
- });
- }));
+ const compiled = fixture.debugElement.nativeElement;
+ expect(compiled.querySelector('h1').innerText).toContain('TRACK NAME');
+ })));
});
});
diff --git a/manuscript/code/routes/music/test/mocks/routes.ts b/manuscript/code/routes/music/test/mocks/routes.ts
deleted file mode 100644
index 5b3b491..0000000
--- a/manuscript/code/routes/music/test/mocks/routes.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import {provide} from '@angular/core';
-import {
-
-
-
- ComponentInstruction,
- Router,
- RouteParams
-} from '@angular/router-deprecated';
-import {Location, LocationStrategy} from '@angular/common';
-import {ResolvedInstruction} from '@angular/router-deprecated/src/instruction';
-import {SpyObject} from './helper';
-
-
-export class MockRouteParams extends SpyObject {
- private ROUTE_PARAMS = {};
-
- constructor() { super(RouteParams); }
-
- set(key: string, value: string) {
- this.ROUTE_PARAMS[key] = value;
- }
-
- get(key: string) {
- return this.ROUTE_PARAMS[key];
- }
-}
-
-export class MockRouter extends SpyObject {
- constructor() { super(Router); }
- isRouteActive(s) { return true; }
- generate(s) {
- let klass: any = ComponentInstruction; // hack b/c ComponentInstruction constructor typing isn't exposed
- let instruction: ComponentInstruction = new klass('detail', [], null, null, true, '0', null, 'Detail');
- return new ResolvedInstruction(instruction, null, {});
- }
-}
-export class MockLocationStrategy extends SpyObject {
- constructor() { super(LocationStrategy); }
-}
-export class MockLocation extends SpyObject {
- constructor() { super(Location); }
-}
-
-export class MockRouterProvider {
- mockRouter: MockRouter = new MockRouter();
- mockRouteParams: MockRouteParams = new MockRouteParams();
- mockLocationStrategy: MockLocationStrategy = new MockLocationStrategy();
- mockLocation: MockLocation = new MockLocation();
-
- setRouteParam(key: string, value: any) {
- this.mockRouteParams.set(key, value);
- }
-
- getProviders(): Array<any> {
- return [
- provide(Router, {useValue: this.mockRouter}),
- provide(RouteParams, {useValue: this.mockRouteParams}),
- provide(Location, {useValue: this.mockLocation}),
- provide(LocationStrategy, {useValue: this.mockLocationStrategy})
- ];
- }
-}
diff --git a/manuscript/code/routes/music/test/mocks/spotify.ts b/manuscript/code/routes/music/test/mocks/spotify.ts
index 36fafba..7bef2ba 100644
--- a/manuscript/code/routes/music/test/mocks/spotify.ts
+++ b/manuscript/code/routes/music/test/mocks/spotify.ts
@@ -1,6 +1,5 @@
import {provide} from '@angular/core';
import {SpyObject} from './helper';
-
import {SpotifyService} from '../../app/ts/services/SpotifyService';
export class MockSpotifyService extends SpyObject {
diff --git a/manuscript/code/routes/music/test/services/SpotifyService.spec.ts b/manuscript/code/routes/music/test/services/SpotifyService.spec.ts
index d8b6ada..66728bc 100644
--- a/manuscript/code/routes/music/test/services/SpotifyService.spec.ts
+++ b/manuscript/code/routes/music/test/services/SpotifyService.spec.ts
@@ -4,9 +4,8 @@ import {
expect,
inject,
fakeAsync,
- afterEach,
- beforeEachProviders,
tick,
+ addProviders
} from '@angular/core/testing';
import {MockBackend} from '@angular/http/testing';
import {provide} from '@angular/core';
@@ -21,15 +20,17 @@ import {
import {SpotifyService} from '../../app/ts/services/SpotifyService';
describe('SpotifyService', () => {
- beforeEachProviders(() => {
- return [
+ beforeEach(() => {
+ addProviders([
BaseRequestOptions,
MockBackend,
SpotifyService,
- provide(Http, {useFactory: (backend: ConnectionBackend, defaultOptions: BaseRequestOptions) => {
+ provide(Http, {
+ useFactory: (backend: ConnectionBackend,
+ defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
}, deps: [MockBackend, BaseRequestOptions]}),
- ]
+ ]);
});
// sets up an expectation that the correct URL will being requested
diff --git a/manuscript/code/routes/nested/app/ts/app.ts b/manuscript/code/routes/nested/app/ts/app.ts
index f47ff14..f60a2fa 100644
--- a/manuscript/code/routes/nested/app/ts/app.ts
+++ b/manuscript/code/routes/nested/app/ts/app.ts
@@ -5,10 +5,10 @@ import {bind, Component} from '@angular/core';
import {bootstrap} from '@angular/platform-browser-dynamic';
import {
ROUTER_DIRECTIVES,
- ROUTER_BINDINGS,
+ provideRouter,
Router,
- RouteConfig,
-} from '@angular/router-deprecated';
+ RouterConfig
+} from '@angular/router';
import {LocationStrategy, HashLocationStrategy} from '@angular/common';
@@ -16,7 +16,10 @@ import {LocationStrategy, HashLocationStrategy} from '@angular/common';
* Components
*/
import {HomeComponent} from 'components/HomeComponent';
-import {ProductsComponent} from 'components/ProductsComponent';
+import {
+ routes as childRoutes,
+ ProductsComponent
+} from 'components/ProductsComponent';
/*
* Webpack
@@ -31,8 +34,8 @@ require('css/styles.scss');
<div class="container">
<h1>Router Sample</h1>
<div class="navLinks">
- <a [routerLink]="['Home']">Home</a>
- <a [routerLink]="['Products']">Products</a>
+ <a [routerLink]="['/home']">Home</a>
+ <a [routerLink]="['/products']">Products</a>
</div>
</div>
</div>
@@ -44,16 +47,18 @@ require('css/styles.scss');
</div>
`
})
-@RouteConfig([
- { path: '/home', name: 'Home', component: HomeComponent, useAsDefault: true },
- { path: '/products/...', name: 'Products', component: ProductsComponent },
-])
class RoutesDemoApp {
constructor(public router: Router) {
}
}
+const routes: RouterConfig = [
+ { path: '', redirectTo: 'home', terminal: true },
+ { path: 'home', component: HomeComponent },
+ { path: 'products', component: ProductsComponent, children: childRoutes }
+];
+
bootstrap(RoutesDemoApp, [
- ROUTER_BINDINGS,
+ provideRouter(routes),
bind(LocationStrategy).toClass(HashLocationStrategy)
]);
diff --git a/manuscript/code/routes/nested/app/ts/components/ProductsComponent.ts b/manuscript/code/routes/nested/app/ts/components/ProductsComponent.ts
index d01dc7a..7927945 100644
--- a/manuscript/code/routes/nested/app/ts/components/ProductsComponent.ts
+++ b/manuscript/code/routes/nested/app/ts/components/ProductsComponent.ts
@@ -3,11 +3,11 @@
*/
import {Component} from '@angular/core';
import {
+ ActivatedRoute,
+ ROUTER_DIRECTIVES,
Router,
- RouterOutlet,
- RouteConfig,
- RouterLink
-} from '@angular/router-deprecated';
+ RouterConfig
+} from '@angular/router';
/*
* Components
@@ -19,14 +19,14 @@ import {ByIdComponent} from 'components/products/ByIdComponent';
@Component({
selector: 'products',
- directives: [RouterOutlet, RouterLink],
+ directives: [ROUTER_DIRECTIVES],
template: `
<h2>Products</h2>
<div class="navLinks">
- <a [routerLink]="['./Main']">Main</a> |
- <a [routerLink]="['./Interest']">Interest</a> |
- <a [routerLink]="['./Sportify']">Sportify</a> |
+ <a [routerLink]="['./main']">Main</a> |
+ <a [routerLink]="['./interest']">Interest</a> |
+ <a [routerLink]="['./sportify']">Sportify</a> |
Enter id: <input #id size="6">
<button (click)="goToProduct(id.value)">Go</button>
</div>
@@ -36,17 +36,20 @@ import {ByIdComponent} from 'components/products/ByIdComponent';
</div>
`
})
-@RouteConfig([
- { path: '/main', name: 'Main', component: MainComponent, useAsDefault: true },
- { path: '/:id', name: 'ById', component: ByIdComponent },
- { path: '/interest', name: 'Interest', component: InterestComponent },
- { path: '/sportify', name: 'Sportify', component: SportifyComponent },
-])
+
export class ProductsComponent {
- constructor(public router: Router) {
+ constructor(private router: Router, private route: ActivatedRoute) {
}
- goToProduct(id: string): void {
- this.router.navigate(['./ById', {id: id}]);
+ goToProduct(id:string): void {
+ this.router.navigate(['./', id], {relativeTo: this.route});
}
}
+
+export const routes: RouterConfig = [
+ { path: '', redirectTo: 'main' },
+ { path: 'main', component: MainComponent },
+ { path: ':id', component: ByIdComponent },
+ { path: 'interest', component: InterestComponent },
+ { path: 'sportify', component: SportifyComponent },
+];
diff --git a/manuscript/code/routes/nested/app/ts/components/products/ByIdComponent.ts b/manuscript/code/routes/nested/app/ts/components/products/ByIdComponent.ts
index 19dccee..e7e270f 100644
--- a/manuscript/code/routes/nested/app/ts/components/products/ByIdComponent.ts
+++ b/manuscript/code/routes/nested/app/ts/components/products/ByIdComponent.ts
@@ -1,8 +1,8 @@
/*
* Angular
*/
-import {Component} from '@angular/core';
-import {RouteParams} from '@angular/router-deprecated';
+import { Component } from '@angular/core';
+import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'byid',
@@ -11,7 +11,7 @@ import {RouteParams} from '@angular/router-deprecated';
export class ByIdComponent {
id: string;
- constructor(public routeParams: RouteParams) {
- this.id = routeParams.get('id');
+ constructor(public route: ActivatedRoute) {
+ route.params.subscribe(params => { this.id = params['id']; });
}
}
diff --git a/manuscript/code/routes/nested/package.json b/manuscript/code/routes/nested/package.json
index 0659e9a..81db4dd 100644
--- a/manuscript/code/routes/nested/package.json
+++ b/manuscript/code/routes/nested/package.json
@@ -11,13 +11,14 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"@angular/router-deprecated": "2.0.0-rc.2",
"base64id": "0.1.0",
"bootstrap-sass": "3.3.5",
diff --git a/manuscript/code/rxjs/chat/package.json b/manuscript/code/rxjs/chat/package.json
index 5f821c8..4b0ad18 100644
--- a/manuscript/code/rxjs/chat/package.json
+++ b/manuscript/code/rxjs/chat/package.json
@@ -6,7 +6,7 @@
"scripts": {
"go": "./node_modules/.bin/webpack-dev-server --display-reasons --display-chunks",
"clean": "true",
- "test": "karma start"
+ "test": "karma start --single-run"
},
"repository": {
"type": "git",
@@ -15,15 +15,16 @@
"author": "Nate Murray <nate@fullstack.io>",
"license": "MIT",
"dependencies": {
- "@angular/common": "2.0.0-rc.2",
- "@angular/compiler": "2.0.0-rc.2",
- "@angular/core": "2.0.0-rc.2",
- "@angular/http": "2.0.0-rc.2",
- "@angular/platform-browser": "2.0.0-rc.2",
- "@angular/platform-browser-dynamic": "2.0.0-rc.2",
- "@angular/router": "2.0.0-rc.2",
+ "@angular/common": "2.0.0-rc.4",
+ "@angular/compiler": "2.0.0-rc.4",
+ "@angular/core": "2.0.0-rc.4",
+ "@angular/forms": "0.2.0",
+ "@angular/http": "2.0.0-rc.4",
+ "@angular/platform-browser": "2.0.0-rc.4",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.4",
+ "@angular/router": "3.0.0-beta.1",
"base64id": "0.1.0",
- "core-js": "^2.2.2",
+ "core-js": "2.2.2",
"lodash": "3.10.1",
"moment": "2.10.6",
"optimist": "0.6.1",
@@ -64,7 +65,7 @@
"script-loader": "0.6.1",
"style-loader": "0.12.3",
"traceur-loader": "0.6.3",
- "ts-helpers": "^1.1.1",
+ "ts-helpers": "1.1.1",
"ts-loader": "0.7.2",
"tslint-loader": "1.0.1",
"typescript": "1.7.3",
diff --git a/manuscript/code/rxjs/chat/package.json.orig b/manuscript/code/rxjs/chat/package.json.orig
new file mode 100644
index 0000000..5f534d3
--- /dev/null
+++ b/manuscript/code/rxjs/chat/package.json.orig
@@ -0,0 +1,82 @@
+{
+ "name": "angular2-rxjs-chat",
+ "version": "1.0.0",
+ "description": "Chat App with Angular 2 and RxJS",
+ "main": "index.js",
+ "scripts": {
+ "go": "./node_modules/.bin/webpack-dev-server --display-reasons --display-chunks",
+ "clean": "true",
+ "test": "karma start"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/ng-book/angular2-rxjs-chat.git"
+ },
+ "author": "Nate Murray <nate@fullstack.io>",
+ "license": "MIT",
+ "dependencies": {
+ "@angular/common": "2.0.0-rc.2",
+ "@angular/compiler": "2.0.0-rc.2",
+ "@angular/core": "2.0.0-rc.2",
+ "@angular/http": "2.0.0-rc.2",
+ "@angular/platform-browser": "2.0.0-rc.2",
+ "@angular/platform-browser-dynamic": "2.0.0-rc.2",
+ "@angular/router": "2.0.0-rc.2",
+<<<<<<< HEAD
+ "@angular/router-deprecated": "2.0.0-rc.2",
+=======
+>>>>>>> 70d6a7f38c5ed937f5676bcc79fbc05ae93fde2a
+ "base64id": "0.1.0",
+ "core-js": "2.2.2",
+ "lodash": "3.10.1",
+ "moment": "2.10.6",
+ "optimist": "0.6.1",
+ "reflect-metadata": "0.1.3",
+ "rxjs": "5.0.0-beta.6",
+ "tslint": "3.7.0-dev.2",
+ "typescript": "1.9.0-dev.20160409",
+ "typings": "0.8.1",
+ "underscore": "1.8.3",
+ "uuid": "2.0.1",
+ "zone.js": "0.6.12"
+ },
+ "devDependencies": {
+ "bootstrap-sass": "3.3.5",
+ "chunk-manifest-webpack-plugin": "0.0.1",
+ "css-loader": "0.15.5",
+ "exports-loader": "0.6.2",
+ "expose-loader": "0.7.1",
+ "extract-text-webpack-plugin": "0.8.2",
+ "file-loader": "0.8.4",
+ "html-webpack-plugin": "1.6.0",
+ "imports-loader": "0.6.4",
+ "jasmine-core": "2.3.4",
+ "karma": "0.13.9",
+ "karma-chrome-launcher": "0.2.0",
+ "karma-jasmine": "0.3.6",
+ "karma-phantomjs-launcher": "0.2.1",
+ "karma-sourcemap-loader": "0.3.5",
+ "karma-spec-reporter": "0.0.20",
+ "karma-webpack": "1.7.0",
+ "live-server": "0.7.1",
+ "node-sass": "3.4.2",
+ "on-build-webpack": "0.1.0",
+ "phantomjs": "1.9.18",
+ "phantomjs-polyfill": "0.0.1",
+ "raw-loader": "0.5.1",
+ "sass-loader": "1.0.2",
+ "script-loader": "0.6.1",
+ "style-loader": "0.12.3",
+ "traceur-loader": "0.6.3",
+ "ts-helpers": "1.1.1",
+ "ts-loader": "0.7.2",
+ "tslint-loader": "1.0.1",
+ "typescript": "1.7.3",
+ "url-loader": "0.5.6",
+ "val-loader": "0.5.0",
+ "webpack": "1.12.9",
+ "webpack-dev-server": "1.12.1",
+ "webpack-notifier": "1.2.1",
+ "webpack-reload-plugin": "0.1.2"
+ }
+}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment