diff --git a/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.1.ts b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.1.ts index 6713ce4dc7..2f5081bdce 100644 --- a/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.1.ts +++ b/public/docs/_examples/toh-5/ts/src/app/hero-detail.component.1.ts @@ -3,7 +3,7 @@ // is solely for containing the transitory state of the imports. // #docregion added-imports -// Keep the Input import for now, we'll remove it later: +// Keep the Input import for now, you'll remove it later: import { Component, Input, OnInit } from '@angular/core'; import { ActivatedRoute, Params } from '@angular/router'; import { Location } from '@angular/common'; diff --git a/public/docs/_examples/toh-5/ts/src/app/heroes.component.css b/public/docs/_examples/toh-5/ts/src/app/heroes.component.css index 35e45af98d..b49fa0a419 100644 --- a/public/docs/_examples/toh-5/ts/src/app/heroes.component.css +++ b/public/docs/_examples/toh-5/ts/src/app/heroes.component.css @@ -1,3 +1,4 @@ +/* #docregion */ .selected { background-color: #CFD8DC !important; color: white; diff --git a/public/docs/ts/latest/tutorial/toh-pt4.jade b/public/docs/ts/latest/tutorial/toh-pt4.jade index 40c357ecbf..c312124ab6 100644 --- a/public/docs/ts/latest/tutorial/toh-pt4.jade +++ b/public/docs/ts/latest/tutorial/toh-pt4.jade @@ -92,7 +92,7 @@ code-example(language="sh" class="code-shell"). :marked ### Getting hero data - Add a `getHeroes` method stub. + Add a `getHeroes()` method stub. +makeExample('toh-4/ts/src/app/hero.service.1.ts', 'getHeroes-stub', 'src/app/hero.service.ts (getHeroes stub)')(format=".") @@ -117,7 +117,7 @@ code-example(language="sh" class="code-shell"). +makeExample('toh-4/ts/src/app/app.component.1.ts', 'heroes-prop', 'src/app/app.component.ts (heroes property)')(format=".") :marked ### Return mocked hero data - Back in the `HeroService`, import the mock `HEROES` and return it from the `getHeroes` method. + Back in the `HeroService`, import the mock `HEROES` and return it from the `getHeroes()` method. The `HeroService` looks like this: +makeExample('toh-4/ts/src/app/hero.service.1.ts', 'full', 'src/app/hero.service.ts')(format=".") @@ -184,7 +184,7 @@ code-example(format="nocode"). The `AppComponent`, as well as its child components, can use that service to get hero data. a#child-component :marked - ### *getHeroes* in the *AppComponent* + ### *getHeroes()* in the *AppComponent* The service is in a `heroService` private variable. You could call the service and get the data in one line. @@ -198,12 +198,12 @@ a#child-component ### The *ngOnInit* lifecycle hook `AppComponent` should fetch and display hero data with no issues. - You might be tempted to call the `getHeroes` method in a constructor, but + You might be tempted to call the `getHeroes()` method in a constructor, but a constructor should not contain complex logic, especially a constructor that calls a server, such as as a data access method. The constructor is for simple initializations, like wiring constructor parameters to properties. - To have Angular call `getHeroes`, you can implement the Angular *ngOnInit lifecycle hook*. + To have Angular call `getHeroes()`, you can implement the Angular *ngOnInit lifecycle hook*. Angular offers interfaces for tapping into critical moments in the component lifecycle: at creation, after each change, and at its eventual destruction. @@ -221,7 +221,7 @@ code-example(format="nocode"). export class AppComponent implements OnInit {} :marked Write an `ngOnInit` method with the initialization logic inside. Angular will call it - at the right time. In this case, initialize by calling `getHeroes`. + at the right time. In this case, initialize by calling `getHeroes()`. +makeExcerpt('toh-4/ts/src/app/app.component.1.ts', 'ng-on-init', 'app/app.component.ts') :marked The app should run as expected, showing a list of heroes and a hero detail view @@ -231,15 +231,17 @@ code-example(format="nocode"). :marked ## Async services and !{_Promise}s The `HeroService` returns a list of mock heroes immediately; - its `getHeroes` signature is synchronous. + its `getHeroes()` signature is synchronous. +makeExample('toh-4/ts/src/app/app.component.1.ts', 'get-heroes')(format=".") :marked Eventually, the hero data will come from a remote server. - When using the remote server, users don't have to wait for the server to respond - and you aren't able to block the UI during the wait. + When using a remote server, users don't have to wait for the server to respond; + additionally, you aren't able to block the UI during the wait. :marked - Instead, you can use *!{_Promise}s*, which is an asynchronous technique that changes the signature of the `getHeroes` method. + To coordinate the view with the response, + you can use *!{_Promise}s*, which is an asynchronous + technique that changes the signature of the `getHeroes()` method. ### The hero service makes a !{_Promise} @@ -253,7 +255,7 @@ code-example(format="nocode"). [Exploring ES6](http://http://exploringjs.com/es6.html). :marked - Update the `HeroService` with this !{_Promise}-returning `getHeroes` method: + Update the `HeroService` with this !{_Promise}-returning `getHeroes()` method: +makeExample('toh-4/ts/src/app/hero.service.ts', 'get-heroes', 'src/app/hero.service.ts (excerpt)')(format=".") :marked You're still mocking the data. You're simulating the behavior of an ultra-fast, zero-latency server, @@ -268,7 +270,7 @@ code-example(format="nocode"). You have to change the implementation to *act on the !{_Promise} when it resolves*. When the !{_Promise} resolves successfully, you'll have heroes to display. - Pass the callback function as an argument to the !{_Promise}'s `then` method: + Pass the callback function as an argument to the !{_Promise}'s `then()` method: +makeExample('toh-4/ts/src/app/app.component.ts', 'get-heroes', 'src/app/app.component.ts (getHeroes - revised)')(format=".") .l-sub-section :marked @@ -334,20 +336,20 @@ code-example(format="nocode"). ## The road ahead The Tour of Heroes has become more reusable using shared components and services. The next goal is to create a dashboard, add menu links that route between the views, and format data in a template. - As the app evolves, you'll learn how to design it to make it easier to grow and maintain. + As the app evolves, you'll discover how to design it to make it easier to grow and maintain. - You learn about Angular component router and navigation among the views in the [next tutorial](toh-pt5.html) page. + Read about the Angular component router and navigation among the views in the [next tutorial](toh-pt5.html) page. .l-main-section :marked ## Appendix: Take it slow To simulate a slow connection, - import the `Hero` symbol and add the following `getHeroesSlowly` method to the `HeroService`. + import the `Hero` symbol and add the following `getHeroesSlowly()` method to the `HeroService`. +makeExample('toh-4/ts/src/app/hero.service.ts', 'get-heroes-slowly', 'app/hero.service.ts (getHeroesSlowly)')(format=".") :marked - Like `getHeroes`, it also returns a !{_Promise}. + Like `getHeroes()`, it also returns a !{_Promise}. But this !{_Promise} waits two seconds before resolving the !{_Promise} with mock heroes. - Back in the `AppComponent`, replace `heroService.getHeroes` with `heroService.getHeroesSlowly` + Back in the `AppComponent`, replace `getHeroes()` with `getHeroesSlowly()` and see how the app behaves. diff --git a/public/docs/ts/latest/tutorial/toh-pt5.jade b/public/docs/ts/latest/tutorial/toh-pt5.jade index 0981cf4d2c..29c9bac19c 100644 --- a/public/docs/ts/latest/tutorial/toh-pt5.jade +++ b/public/docs/ts/latest/tutorial/toh-pt5.jade @@ -12,8 +12,8 @@ block includes * Add a *Dashboard* view. * Add the ability to navigate between the *Heroes* and *Dashboard* views. - * When users click a hero name in either view, they should navigate to a detail view of the selected hero. - * When users click a *deep link* in an email, the detail view for a particular hero should open. + * When users click a hero name in either view, navigate to a detail view of the selected hero. + * When users click a *deep link* in an email, open the detail view for a particular hero. When you’re done, users will be able to navigate the app like this: @@ -37,7 +37,6 @@ figure.image-display :marked ## Where you left off Before continuing with the Tour of Heroes, verify that you have the following structure. - If not, go back to the previous pages. block intro-file-tree .filetree @@ -215,14 +214,14 @@ block router-config-intro :marked ### Make the router available - Add the initial route configuration, `RouterModule`, to the `AppModule` imports !{_array}. + Import the `RouterModule` and add it to the `AppModule` imports !{_array}. +makeExcerpt('src/app/app.module.2.ts (app routing)', '') .l-sub-section :marked - The `forRoot` method is called because a configured router is provided at the app's root. - The `forRoot` method supplies the Router service providers and directives needed for routing, and + The `forRoot()` method is called because a configured router is provided at the app's root. + The `forRoot()` method supplies the Router service providers and directives needed for routing, and performs the initial navigation based on the current browser URL. - var _heroesRoute = _docsFor == 'dart' ? "'Heroes'" : 'heroes' @@ -260,7 +259,7 @@ block routerLink [Routing & Navigation](../guide/router.html#) page. :marked - Refresh the browser. The app title and heroes link, but not the heroes list, display. + Refresh the browser. The browser displays the app title and heroes link, but not the heroes list. .l-sub-section :marked @@ -269,7 +268,7 @@ block routerLink Soon you'll add a route that matches the path `/`. :marked - Click the *Heroes* navigation link. The browser bar updates to `/heroes` + Click the *Heroes* navigation link. The address bar updates to `/heroes` and the list of heroes displays. `AppComponent` now looks like this: @@ -361,13 +360,13 @@ block templateUrl-path-resolution :marked `*ngFor` is used again to iterate over a list of heroes and display their names. - The extra `
int.parse
static method' : 'JavaScript (+) operator'
:marked
@@ -534,13 +533,13 @@ block extract-id
section of the [Routing & Navigation](../guide/router.html) page,
the `Router` manages the observables it provides and localizes
the subscriptions. The subscriptions are cleaned up when the component is destroyed, protecting against
- memory leaks, so you don't need to unsubscribe from the route params `Observable`.
+ memory leaks, so you don't need to unsubscribe from the route `params` `Observable`.
:marked
### Add *HeroService.getHero*
- In the previous code snippet, `HeroService` doesn't have a `getHero` method. To fix this issue,
- open `HeroService` and add a `getHero` method that filters the heroes list from `getHeroes` by `id`.
+ In the previous code snippet, `HeroService` doesn't have a `getHero()` method. To fix this issue,
+ open `HeroService` and add a `getHero()` method that filters the heroes list from `getHeroes` by `id`.
+makeExcerpt('src/app/hero.service.ts', 'getHero')
@@ -550,7 +549,7 @@ block extract-id
Users have several ways to navigate *to* the `HeroDetailComponent`.
To navigate somewhere else, users can click one of the two links in the `AppComponent` or click the browser's back button.
- Now add a third option, a `goBack` method that navigates backward one step in the browser's history stack
+ Now add a third option, a `goBack()` method that navigates backward one step in the browser's history stack
using the `Location` service you injected previously.
+makeExcerpt('src/app/hero-detail.component.ts', 'goBack')
@@ -633,8 +632,8 @@ block extract-id
establish key facts about the entire app for the Angular compiler.
It's a good idea to refactor the routing configuration into its own class.
- The current `RouterModule.forRoot()` produces an Angular `ModuleWithProviders`.
- A class dedicated to routing should be a *routing module*.
+ The current `RouterModule.forRoot()` produces an Angular `ModuleWithProviders`,
+ a class dedicated to routing should be a *routing module*.
For more information, see the [Milestone #2: The Routing Module](../guide/router.html#routing-module)
section of the [Routing & Navigation](../guide/router.html) page.
@@ -658,8 +657,8 @@ block extract-id
### Update *AppModule*
- Delete the routing configuration from `AppModule` and import the `AppRoutingModule`
- (*both* with an ES `import` statement *and* by adding it to the `NgModule.imports` list).
+ Delete the routing configuration from `AppModule` and import the `AppRoutingModule`.
+ Use an ES `import` statement *and* add it to the `NgModule.imports` list.
:marked
Here is the revised `AppModule`, compared to its pre-refactor state:
@@ -696,9 +695,6 @@ block extract-id
Add the following HTML fragment at the bottom of the template where the `map
,
+ More importantly, you no longer call `toPromise()`.
+ Instead you return the *Observable* from the the `htttp.get()`,
+ after chaining it to another RxJS operator, map()
,
to extract heroes from the response data.
RxJS operator chaining makes response processing easy and readable.
- See the [discuss below about operators](#rxjs-imports).
+ See the [discussion below about operators](#rxjs-imports).
:marked
### HeroSearchComponent
@@ -422,7 +423,8 @@ block observables-section-intro
Also, add styles for the new component.
+makeExample('src/app/hero-search.component.css')
:marked
- As the user types in the search box, a *keyup* event binding calls the component's `search` method with the new search box value.
+ As the user types in the search box, a *keyup* event binding calls the component's `search()`
+ method with the new search box value.
As expected, the `*ngFor` repeats hero objects from the component's `heroes` property.
@@ -446,7 +448,7 @@ block search-criteria-intro
A `Subject` is a producer of an _observable_ event stream;
`searchTerms` produces an `Observable` of strings, the filter criteria for the name search.
- Each call to `search` puts a new string into this subject's _observable_ stream by calling `next`.
+ Each call to `search()` puts a new string into this subject's _observable_ stream by calling `next()`.
:marked
@@ -470,25 +472,25 @@ block observable-transformers
* `debounceTime(300)` waits until the flow of new string events pauses for 300 milliseconds
before passing along the latest string. You'll never make requests more frequently than 300ms.
* `distinctUntilChanged` ensures that a request is sent only if the filter text changed.
- * `switchMap` calls the search service for each search term that makes it through `debounce` and `distinctUntilChanged`.
+ * `switchMap()` calls the search service for each search term that makes it through `debounce` and `distinctUntilChanged`.
It cancels and discards previous search observables, returning only the latest search service observable.
.l-sub-section
:marked
With the [switchMap operator](http://www.learnrxjs.io/operators/transformation/switchmap.html)
- (formerly known as "flatMapLatest"),
- every qualifying key event can trigger an `http` method call.
+ (formerly known as `flatMapLatest`),
+ every qualifying key event can trigger an `http()` method call.
Even with a 300ms pause between requests, you could have multiple HTTP requests in flight
and they may not return in the order sent.
- `switchMap` preserves the original request order while returning
+ `switchMap()` preserves the original request order while returning
only the observable from the most recent `http` method call.
Results from prior calls are canceled and discarded.
- If the search text is empty, the `http` method call is also short circuited
+ If the search text is empty, the `http()` method call is also short circuited
and an observable containing an empty array is returned.
- Note that until the service supports that feature, _canceling_ the `HeroSearchService` observable
+ Note that until the service supports that feature, _canceling_ the `HeroSearchService` Observable
doesn't actually abort a pending HTTP request.
For now, unwanted results are discarded.
:marked
@@ -589,7 +591,7 @@ block filetree
You're at the end of your journey, and you've accomplished a lot.
- You added the necessary dependencies to use HTTP in the app.
- You refactored `HeroService` to load heroes from a web API.
- - You extended `HeroService` to support post, put, and delete methods.
+ - You extended `HeroService` to support `post()`, `put()`, and `delete()` methods.
- You updated the components to allow adding, editing, and deleting of heroes.
- You configured an in-memory web API.
- You learned how to use !{_Observable}s.