Skip to content
This repository was archived by the owner on Dec 4, 2017. It is now read-only.

Commit 301aadd

Browse files
Andersonwardbell
Anderson
authored andcommitted
docs(toh-pt6): fix filename typo
1 parent 8569479 commit 301aadd

File tree

1 file changed

+82
-80
lines changed

1 file changed

+82
-80
lines changed

public/docs/ts/latest/tutorial/toh-pt6.jade

Lines changed: 82 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ include ../_util-fns
22

33
:marked
44
# Getting and Saving Data with HTTP
5-
6-
Our stakeholders appreciate our progress.
5+
6+
Our stakeholders appreciate our progress.
77
Now they want to get the hero data from a server, let users add, edit, and delete heroes,
88
and save these changes back to the server.
9-
9+
1010
In this chapter we teach our application to make the corresponding http calls to a remote server's web api.
1111
:marked
12-
[Run the live example](/resources/live-examples/toh-6/ts/plnkr.html).
13-
12+
[Run the live example](/resources/live-examples/toh-6/ts/plnkr.html).
13+
1414
.l-main-section
1515
:marked
1616
## Where We Left Off
@@ -27,25 +27,25 @@ code-example(format="." language="bash").
2727
:marked
2828
The application runs and updates automatically as we continue to build the Tour of Heroes.
2929

30-
.l-main-section
30+
.l-main-section
3131
:marked
3232
## Prepare for Http
33-
34-
`Http` is ***not*** a core Angular module.
33+
34+
`Http` is ***not*** a core Angular module.
3535
It's Angular's optional approach to web access and it exists as a separate add-on module called `@angular/http`,
36-
shipped in a separate script file as part of the Angular npm package.
37-
36+
shipped in a separate script file as part of the Angular npm package.
37+
3838
Fortunately we're ready to import from `@angular/http` because `systemjs.config` configured *SystemJS* to load that library when we need it.
3939

4040
:marked
4141
### Register (provide) *http* services
4242
Our app will depend upon the Angular `http` service which itself depends upon other supporting services.
4343
The `HTTP_PROVIDERS` array from `@angular/http` library holds providers for the complete set of http services.
44-
44+
4545
We should be able to access these services from anywhere in the application.
4646
So we register them in the `bootstrap` method of `main.ts` where we
4747
launch the application and its root `AppComponent`.
48-
48+
4949
+makeExample('toh-6/ts/app/main.ts','v1','app/main.ts (v1)')(format='.')
5050
:marked
5151
Notice that we supply the `HTTP_PROVIDERS` in an array as the second parameter to the `bootstrap` method.
@@ -57,19 +57,19 @@ code-example(format="." language="bash").
5757

5858
We generally recommend registering application-wide services in the root `AppComponent` *providers*.
5959
Here we're registering in `main` for a special reason.
60-
61-
Our application is in the early stages of development and far from ready for production.
60+
61+
Our application is in the early stages of development and far from ready for production.
6262
We don't even have a web server that can handle requests for heroes.
6363
Until we do, *we'll have to fake it*.
64-
64+
6565
We're going to *trick* the http client into fetching and saving data from
6666
a demo/development service, the *in-memory web api*.
67-
67+
6868
The application itself doesn't need to know and shouldn't know about this.
6969
So we'll slip the *in-memory web api* into the configuration *above* the `AppComponent`.
70-
70+
7171
Here is a version of `main` that performs this trick
72-
+makeExample('toh-6/ts/app/main.ts', 'final', 'app/main.ts (final)')(format=".")
72+
+makeExample('toh-6/ts/app/main.ts', 'final', 'app/main.ts (final)')(format=".")
7373

7474
:marked
7575
We're replacing the default `XHRBackend`, the service that talks to the remote server,
@@ -81,55 +81,55 @@ code-example(format="." language="bash").
8181
.alert.is-helpful
8282
:marked
8383
This chaper is an introduction to the Angular http client.
84-
Please don't be distracted by the details of this backend substitution. Just follow along with the example.
85-
84+
Please don't be distracted by the details of this backend substitution. Just follow along with the example.
85+
8686
Learn more later about the *in-memory web api* in the [Http chapter](../guide/server-communication.html#!#in-mem-web-api).
87-
Remember, the *in-memory web api* is only useful in the early stages of development and for demonstrations such as this Tour of Heroes.
87+
Remember, the *in-memory web api* is only useful in the early stages of development and for demonstrations such as this Tour of Heroes.
8888
Skip it when you have a real web api server.
8989

9090

9191
.l-main-section
9292
:marked
9393
## Heroes and Http
94-
94+
9595
Look at our current `HeroService` implementation
9696
+makeExample('toh-4/ts/app/hero.service.ts', 'get-heroes', 'app/hero.service.ts (getHeroes - old)')(format=".")
9797
:marked
98-
We returned a promise resolved with mock heroes.
98+
We returned a promise resolved with mock heroes.
9999
It may have seemed like overkill at the time, but we were anticipating the
100100
day when we fetched heroes with an http client and we knew that would have to be an asynchronous operation.
101-
101+
102102
That day has arrived! Let's convert `getHeroes()` to use Angular's `Http` client:
103-
103+
104104
+makeExample('toh-6/ts/app/hero.service.ts', 'get-heroes', 'app/hero.service.ts (getHeroes using Http)')(format=".")
105-
105+
106106
:marked
107107
### Http Promise
108108

109109
We're still returning a promise but we're creating it differently.
110-
110+
111111
The Angular `http.get` returns an RxJS `Observable`.
112112
*Observables* are a powerful way to manage asynchronous data flows.
113113
We'll learn about `Observables` *later*.
114-
114+
115115
For *now* we get back on familiar ground by immediately converting that `Observable` to a `Promise` using the `toPromise` operator.
116116
+makeExample('toh-6/ts/app/hero.service.ts', 'to-promise')(format=".")
117117
:marked
118118
Unfortunately, the Angular `Observable` doesn't have a `toPromise` operator ... not out of the box.
119-
The Angular `Observable` is a bare-bones implementation.
120-
119+
The Angular `Observable` is a bare-bones implementation.
120+
121121
There are scores of operators like `toPromise` that extend `Observable` with useful capabilities.
122122
If we want those capabilities, we have to add the operators ourselves.
123123
That's as easy as importing them from the RxJS library like this:
124124
+makeExample('toh-6/ts/app/hero.service.ts', 'rxjs')(format=".")
125125

126126
:marked
127-
### Extracting the data in the *then* callback
127+
### Extracting the data in the *then* callback
128128
In the *promise*'s `then` callback we call the `json` method of the http `Response` to extract the
129129
data within the response.
130130
+makeExample('toh-6/ts/app/hero.service.ts', 'to-data')(format=".")
131131
:marked
132-
That object returned by `json` has a single `data` property.
132+
That object returned by `json` has a single `data` property.
133133
The `data` property holds the array of *heroes* that the caller really wants.
134134
So we grab that array and return it as the resolved promise value.
135135

@@ -138,20 +138,20 @@ code-example(format="." language="bash").
138138
Pay close attention to the shape of the data returned by the server.
139139
This particular *in-memory web api* example happens to return an object with a `data` property.
140140
Your api might return something else.
141-
142-
Adjust the code to match *your web api*.
141+
142+
Adjust the code to match *your web api*.
143143
:marked
144-
The caller is unaware of these machinations. It receives a promise of *heroes* just as it did before.
144+
The caller is unaware of these machinations. It receives a promise of *heroes* just as it did before.
145145
It has no idea that we fetched the heroes from the server.
146146
It knows nothing of the twists and turns required to turn the http response into heroes.
147147
Such is the beauty and purpose of delegating data access to a service like this `HeroService`.
148148
:marked
149149
### Error Handling
150-
150+
151151
At the end of `getHeroes` we `catch` server failures and pass them to an error handler:
152152
+makeExample('toh-6/ts/app/hero.service.ts', 'catch')(format=".")
153153
:marked
154-
This is a critical step!
154+
This is a critical step!
155155
We must anticipate http failures as they happen frequently for reasons beyond our control.
156156

157157
+makeExample('toh-6/ts/app/hero.service.ts', 'error-handler', 'app/hero.service.ts (Error handler)')(format=".")
@@ -160,51 +160,51 @@ code-example(format="." language="bash").
160160

161161
We've also decided to return a user friendly form of the error to
162162
to the caller in a rejected promise so that the caller can display a proper error message to the user.
163-
163+
164164
### Promises are Promises
165-
Although we made significant *internal* changes to `getHeroes()`, the public signature did not change.
165+
Although we made significant *internal* changes to `getHeroes()`, the public signature did not change.
166166
We still return a promise. We won't have to update any of the components that call `getHeroes()`.
167167

168-
.l-main-section
168+
.l-main-section
169169
:marked
170170
## Add, Edit, Delete
171-
172-
Our stakeholders are incredibly pleased with the added flexibility from the api integration, but it doesn't stop there. Next we want to add the capability to add, edit and delete heroes.
173-
174-
We'll complete `HeroService` by creating `post`, `put` and `delete` http calls to meet our new requirements.
171+
172+
Our stakeholders are incredibly pleased with the added flexibility from the api integration, but it doesn't stop there. Next we want to add the capability to add, edit and delete heroes.
173+
174+
We'll complete `HeroService` by creating `post`, `put` and `delete` http calls to meet our new requirements.
175175

176176
:marked
177177
### Post
178-
178+
179179
We are using `post` to add new heroes. Post requests require a little bit more setup than Get requests, but the format is as follows:
180-
180+
181181
+makeExample('toh-6/ts/app/hero.service.ts', 'post-hero', 'app/hero.service.ts (post hero)')(format=".")
182182

183183
:marked
184-
Now we create a header and set the content type to `application/json`. We'll call `JSON.stringify` before we post to convert the hero object to a string.
185-
184+
Now we create a header and set the content type to `application/json`. We'll call `JSON.stringify` before we post to convert the hero object to a string.
185+
186186
### Put
187-
187+
188188
`put` is used to edit a specific hero, but the structure is very similar to a `post` request. The only difference is that we have to change the url slightly by appending the id of the hero we want to edit.
189189

190190
+makeExample('toh-6/ts/app/hero.service.ts', 'put-hero', 'app/hero.service.ts (put hero)')(format=".")
191191

192192
:marked
193193
### Delete
194-
`delete` is used to delete heroes and the format is identical to `put` except for the function name.
194+
`delete` is used to delete heroes and the format is identical to `put` except for the function name.
195195

196196
+makeExample('toh-6/ts/app/hero.service.ts', 'delete-hero', 'app/hero.service.ts (delete hero)')(format=".")
197197

198198
:marked
199199
We add a `catch` to handle our errors for all three cases.
200-
200+
201201
:marked
202202
### Save
203203

204204
We combine the call to the private `post` and `put` methods in a single `save` method. This simplifies the public api and makes the integration with `HeroDetailComponent` easier. `HeroService` determines which method to call based on the state of the `hero` object. If the hero already has an id we know it's an edit. Otherwise we know it's an add.
205205

206206
+makeExample('toh-6/ts/app/hero.service.ts', 'save', 'app/hero.service.ts (save hero)')(format=".")
207-
207+
208208
:marked
209209
After these additions our `HeroService` looks like this:
210210

@@ -213,99 +213,102 @@ code-example(format="." language="bash").
213213
.l-main-section
214214
:marked
215215
## Updating Components
216-
217-
Loading heroes using `Http` required no changes outside of `HeroService`, but we added a few new features as well.
216+
217+
Loading heroes using `Http` required no changes outside of `HeroService`, but we added a few new features as well.
218218
In the following section we will update our components to use our new methods to add, edit and delete heroes.
219-
219+
220220
### Add/Edit in the *HeroDetailComponent*
221-
We already have `HeroDetailComponent` for viewing details about a specific hero. Add and Edit are natural extensions of the detail view, so we are able to reuse `HeroDetailComponent` with a few tweaks. The original component was created to render existing data, but to add new data we have to initialize the `hero` property to an empty `Hero` object.
222-
221+
222+
We already have `HeroDetailComponent` for viewing details about a specific hero.
223+
Add and Edit are natural extensions of the detail view, so we are able to reuse `HeroDetailComponent` with a few tweaks.
224+
The original component was created to render existing data, but to add new data we have to initialize the `hero` property to an empty `Hero` object.
225+
223226
+makeExample('toh-6/ts/app/hero-detail.component.ts', 'ngOnInit', 'app/hero-detail.component.ts (ngOnInit)')(format=".")
224227

225228
:marked
226229
In order to differentiate between add and edit we are adding a check to see if an id is passed in the url. If the id is absent we bind `HeroDetailComponent` to an empty `Hero` object. In either case, any edits made through the UI will be bound back to the same `hero` property.
227230

228231
The next step is to add a save method to `HeroDetailComponent` and call the corresponding save method in `HeroesService`.
229-
232+
230233
+makeExample('toh-6/ts/app/hero-detail.component.ts', 'save', 'app/hero-detail.component.ts (save)')(format=".")
231234

232235
:marked
233236
The same save method is used for both add and edit since `HeroService` will know when to call `post` vs `put` based on the state of the `Hero` object.
234-
237+
235238
After we save a hero, we redirect the browser back to the to the previous page using the `goBack()` method.
236-
239+
237240
+makeExample('toh-6/ts/app/hero-detail.component.ts', 'goback', 'app/hero-detail.component.ts (goBack)')(format=".")
238241

239242
:marked
240243
Here we call `emit` to notify that we just added or modified a hero. `HeroesComponent` is listening for this notification and will automatically refresh the list of heroes to include our recent updates.
241244

242245
.l-sub-section
243246
:marked
244-
The `emit` "handshake" between `HeroDetailComponent` and `HeroesComponent` is an example of component to component communication. This is a topic for another day, but we have detailed information in our <a href="/docs/ts/latest/cookbook/component-communication.html#!#child-to-parent">Component Interaction Cookbook</a>
247+
The `emit` "handshake" between `HeroDetailComponent` and `HeroesComponent` is an example of component to component communication. This is a topic for another day, but we have detailed information in our <a href="/docs/ts/latest/cookbook/component-communication.html#!#child-to-parent">Component Interaction Cookbook</a>
245248

246249
:marked
247250
Here is `HeroDetailComponent` with its new save button.
248-
251+
249252
figure.image-display
250253
img(src='/resources/images/devguide/toh/hero-details-save-button.png' alt="Hero Details With Save Button")
251254

252255
:marked
253256
### Add/Delete in the *HeroesComponent*
254-
257+
255258
The user can *add* a new hero by clicking a button and entering a name.
256259

257260
When the user clicks the *Add New Hero* button, we display the `HeroDetailComponent`.
258261
We aren't navigating to the component so it won't receive a hero `id`;
259262
As we noted above, that is the component's cue to create and present an empty hero.
260-
263+
261264
Add the following HTML to the `heroes.component.html`, just below the hero list (the `*ngFor`).
262265
+makeExample('toh-6/ts/app/heroes.component.html', 'add-hero', 'app/heroes.component.html (add)')(format=".")
263266
:marked
264267
The user can *delete* an existing hero by clicking a delete button next to the hero's name.
265-
268+
266269
Add the following HTML to the `heroes.component.html` right after the name in the repeated `<li>` tag:
267270
+makeExample('toh-6/ts/app/heroes.component.html', 'delete-hero', 'app/heroes.component.html (delete)')(format=".")
268271

269272
:marked
270273
Now let's fix-up the `HeroesComponent` to support the *add* and *delete* actions in the template.
271274
Let's start with *add*.
272-
275+
273276
We're using the `HeroDetailComponent` to capture the new hero information.
274277
We have to tell Angular about that by importing the `HeroDetailComponent` and referencing it in the component metadata `directives` array.
275-
+makeExample('toh-6/ts/app/heroes.component.ts', 'hero-detail-component', 'app/heroes.component.ts (HeroDetailComponent)')(format=".")
278+
+makeExample('toh-6/ts/app/heroes.component.ts', 'hero-detail-component', 'app/heroes.component.ts (HeroDetailComponent)')(format=".")
276279
.l-sub-section
277280
:marked
278281
These are the same lines that we removed in the previous [Routing](toh-pt5.html) chapter.
279282
We didn't know at the time that we'd need the *HeroDetailComponent* again. So we tidied up.
280-
283+
281284
Now we *must* put these lines back. If we don't, Angular will ignore the `<my-hero-detail>`
282285
tag and pushing the *Add New Hero* button will have no visible effect.
283286
:marked
284287
Next we implement the click handler for the *Add New Hero* button.
285288

286-
+makeExample('toh-6/ts/app/heroes.component.ts', 'add', 'app/heroes.component.ts (add)')(format=".")
289+
+makeExample('toh-6/ts/app/heroes.component.ts', 'add', 'app/heroes.component.ts (add)')(format=".")
287290
:marked
288291
The `HeroDetailComponent` does most of the work. All we do is toggle an `*ngIf` flag that
289292
swaps it into the DOM when were add a hero and remove it from the DOM when the user is done.
290-
293+
291294
The *delete* logic is a bit trickier.
292295
+makeExample('toh-6/ts/app/heroes.component.ts', 'delete', 'app/heroes.component.ts (delete)')(format=".")
293296

294297
:marked
295-
Of course we delegate the persistence of hero deletion to the `HeroService`.
298+
Of course we delegate the persistence of hero deletion to the `HeroService`.
296299
But the component is still responsible for updating the display.
297300
So the *delete* method removes the deleted hero from the list.
298301

299302
:marked
300303
### Let's see it
301304
Here are the fruits of labor in action:
302305
figure.image-display
303-
img(src='/resources/images/devguide/toh/toh-http.anim.gif' alt="Heroes List Editting w/ HTTP")
306+
img(src='/resources/images/devguide/toh/toh-http.anim.gif' alt="Heroes List Editting w/ HTTP")
304307

305308
:marked
306309
### Review the App Structure
307310
Let’s verify that we have the following structure after all of our good refactoring in this chapter:
308-
311+
309312
.filetree
310313
.file angular2-tour-of-heroes
311314
.children
@@ -335,20 +338,20 @@ figure.image-display
335338
.file systemjs.config.json
336339
.file tsconfig.json
337340
.file typings.json
338-
339-
.l-main-section
341+
342+
.l-main-section
340343
:marked
341344
## Home Stretch
342-
345+
343346
We are at the end of our journey for now, but we have accomplished a lot.
344347
- We added the necessary dependencies to use Http in our application.
345348
- We refactored HeroService to load heroes from an api.
346349
- We extended HeroService to support post, put and delete calls.
347350
- We updated our components to allow adding, editing and deleting of heroes.
348351
- We configured an in-memory web api.
349-
352+
350353
Below is a summary of the files we changed.
351-
354+
352355
+makeTabs(
353356
`toh-6/ts/app/app.component.ts,
354357
toh-6/ts/app/heroes.component.ts,
@@ -363,5 +366,4 @@ figure.image-display
363366
hero-detail.comp...ts,
364367
hero-detail.comp...html,
365368
hero.service.ts`
366-
)
367-
369+
)

0 commit comments

Comments
 (0)