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

Commit 64d76de

Browse files
committed
docs:(TOH-Http-Chapter) - made updated based on feedback
1 parent 2b98e2f commit 64d76de

File tree

7 files changed

+85
-61
lines changed

7 files changed

+85
-61
lines changed

public/docs/_examples/toh-6/ts/app/app.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { HTTP_PROVIDERS } from 'angular2/http';
1717
//These imports are only required for the in-memory web api
1818
import { InMemoryBackendService, SEED_DATA } from 'a2-in-memory-web-api/core';
1919
import { XHRBackend } from 'angular2/http';
20-
import { HeroData } from './hero-data';
20+
import { InMemoryDataService } from './in-memory-data.service';
2121

2222
@Component({
2323
selector: 'my-app',
@@ -40,7 +40,7 @@ import { HeroData } from './hero-data';
4040

4141
// Only required for the in-memory web api
4242
provide(XHRBackend, { useClass: InMemoryBackendService }), // in-mem server
43-
provide(SEED_DATA, { useClass: HeroData }) // in-mem server data
43+
provide(SEED_DATA, { useClass: InMemoryDataService }) // in-mem server data
4444
]
4545
})
4646
//#enddocregion http

public/docs/_examples/toh-6/ts/app/hero-detail.component.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { HeroService } from './hero.service';
1313
export class HeroDetailComponent implements OnInit {
1414
@Input() hero: Hero;
1515
@Output() updateHeroes = new EventEmitter();
16+
error:any;
1617

1718
constructor(
1819
private _heroService: HeroService,
@@ -33,10 +34,12 @@ export class HeroDetailComponent implements OnInit {
3334
// #enddocregion ngOnInit
3435
// #docregion save
3536
save(){
36-
this._heroService.save(this.hero)
37-
.then(r => {
38-
this.updateHeroes.emit(r);
39-
});
37+
this._heroService
38+
.save(this.hero)
39+
.then(response => {
40+
this.updateHeroes.emit(response);
41+
})
42+
.catch(error => this.error = error);//TODO: Display error message
4043
}
4144
// #enddocregion save
4245
goBack() {

public/docs/_examples/toh-6/ts/app/hero.service.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,24 @@ export class HeroService {
1414

1515
//#docregion get-heroes
1616
getHeroes() {
17-
return this._http.get(this._heroesUrl).toPromise()
18-
.then((res:Response) => res.json())
19-
.then(res => res.data)
20-
.catch(this._handleError);
17+
return this._http
18+
.get(this._heroesUrl).toPromise()
19+
.then((res:Response) => res.json().data)
20+
.catch(this._handleError);
2121
}
2222
//#enddocregion get-heroes
2323

2424
getHero(id: number) {
25-
return this.getHeroes().then(
26-
heroes => heroes.filter((hero:Hero) => hero.id === id)[0]
27-
);
25+
return this.getHeroes()
26+
.then(heroes => heroes.filter((hero:Hero) => hero.id === id)[0]);
2827
}
2928

3029
//#docregion save
3130
save(hero:Hero){
3231
if(hero.id){
3332
return this._put(hero);
3433
}
35-
else{
36-
return this._post(hero);
37-
}
34+
return this._post(hero);
3835
}
3936
//#enddocregion save
4037

@@ -45,7 +42,9 @@ export class HeroService {
4542

4643
let url = `${this._heroesUrl}/${hero.id}`;
4744

48-
return this._http.delete(url,headers).toPromise()
45+
return this._http
46+
.delete(url,headers)
47+
.toPromise()
4948
.catch(this._handleError);
5049
}
5150
//#enddocregion delete-hero
@@ -55,9 +54,10 @@ export class HeroService {
5554
let headers = new Headers();
5655
headers.append('Content-Type', 'application/json');
5756

58-
return this._http.post(this._heroesUrl, JSON.stringify(hero), {headers:headers}).toPromise()
57+
return this._http
58+
.post(this._heroesUrl, JSON.stringify(hero), {headers:headers})
59+
.toPromise()
5960
.catch(this._handleError);
60-
6161
}
6262
//#enddocregion post-hero
6363

@@ -68,14 +68,17 @@ export class HeroService {
6868

6969
let url = `${this._heroesUrl}/${hero.id}`;
7070

71-
return this._http.put(url, JSON.stringify(hero), {headers:headers}).toPromise()
71+
return this._http
72+
.put(url, JSON.stringify(hero), {headers:headers})
73+
.toPromise()
7274
.catch(this._handleError);
7375
}
7476
//#enddocregion put-hero
7577

7678
//#docregion error-handler
7779
private _handleError(error:any){
7880
console.log('An error occurred:' + error);
81+
return Promise.reject(error);
7982
}
8083
//#enddocregion error-handler
8184
}

public/docs/_examples/toh-6/ts/app/heroes.component.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
<!-- #docplaster -->
21
<!-- #docregion -->
32
<h2>My Heroes</h2>
43
<ul class="heroes">

public/docs/_examples/toh-6/ts/app/heroes.component.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// #docplaster
21
// #docregion
32
import { Component, OnInit } from 'angular2/core';
43
import { Router } from 'angular2/router';
@@ -17,14 +16,17 @@ export class HeroesComponent implements OnInit {
1716
heroes: Hero[];
1817
selectedHero: Hero;
1918
addingHero = false;
19+
error:any;
2020

2121
constructor(
2222
private _router: Router,
2323
private _heroService: HeroService) { }
2424

2525
getHeroes() {
26-
this._heroService.getHeroes()
27-
.then(heroes => this.heroes = heroes);
26+
this._heroService
27+
.getHeroes()
28+
.then(heroes => this.heroes = heroes)
29+
.catch(error => this.error = error);//TODO: Display error message
2830
}
2931

3032
addHero(){
@@ -35,11 +37,12 @@ export class HeroesComponent implements OnInit {
3537
// #docregion delete
3638
delete(hero:Hero, event:any){
3739
event.stopPropagation();
38-
this._heroService.delete(hero)
39-
.then(r => {
40+
this._heroService
41+
.delete(hero)
42+
.then(res => {
4043
this.heroes = this.heroes.filter(h => h.id !== hero.id);
41-
}
42-
);
44+
})
45+
.catch(error => this.error = error);//TODO: Display error message
4346
}
4447
// #enddocregion delete
4548

public/docs/_examples/toh-6/ts/app/hero-data.ts renamed to public/docs/_examples/toh-6/ts/app/in-memory-data.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// #docregion
2-
export class HeroData {
2+
export class InMemoryDataService {
33
createDb() {
44
let heroes = [
55
{ "id": 1, "name": "Windstorm" },

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

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ include ../_util-fns
33
:marked
44
# Http
55

6-
Our application has become a huge success and our stakeholders have already expanded the vision to include integration with a hero api.
6+
Our application has become a huge success and our stakeholders have expanded the vision to include integration with a hero api.
77

8-
The current solution limits us to a fixed set of heroes, but integration with the api will allow us to load heroes dynamically from a database. We will also be able to add, edit and delete heroes.
8+
The current solution limits us to a fixed set of heroes, but integration with a web server api will make our application much more flexible. We will also be able to add, edit and delete heroes.
99

10-
In this chapter we will show how to integrate the http based api with our existing application.
10+
In this chapter we will connect our Angular 2 services to make http calls to our new api.
1111
:marked
1212
[Run the live example](/resources/live-examples/toh-6/ts/plnkr.html).
1313

@@ -72,14 +72,14 @@ code-example(format="." language="bash").
7272

7373
In our previous implementation we created a promise ourselves and resolved it immediately. When using `Http` we no longer have to create the promise manually. Instead `Http` will create it for us, but we have to call `toPromise()` to get it.
7474

75-
In the first `then` we convert the response to a json object by calling `res.json()`.
75+
In the `then` we convert the response to a json object by calling `res.json()`.
7676

77-
Our api follows the convention of returning the result wrapped in a `data` property, but we don't want to expose this to the caller, so we flatten the response in the second `then` by returning `res.data`.
77+
Our api follows the convention of returning the result wrapped in a `data` property, but we don't want to expose this to the caller, so we flatten the response by returning `res.data`.
7878

7979
:marked
8080
### Error Handling
8181

82-
At the end we are calling `catch` and passing in an error handler. This is an important step since it allows us to catch any error returned by the api.
82+
At the end we are calling `catch` and passing in an error handler. This is an important step since it allows us to catch any error returned by the api. In the service we log the error and return the rejected promise. It's important that the service returns the rejected promise to the component, so that we can display an error message to the user.
8383
+makeExample('toh-6/ts/app/hero.service.ts', 'error-handler', 'app/hero.service.ts (Error handler)')(format=".")
8484

8585
:marked
@@ -88,25 +88,25 @@ code-example(format="." language="bash").
8888

8989
.l-sub-section
9090
:marked
91-
We want to point out that a promise is not the only way to process http calls. We will encounter other approaches such as Observables in subsequent chapters, but for the purposes of this article we are sticking to promises.
91+
We realize there are alternatives to promises for processing http calls. We will encounter other approaches such as Observables in subsequent chapters, but for the purposes of this article we are sticking to promises.
9292

9393
.l-main-section
9494
:marked
9595
## Add, Edit, Delete
9696

9797
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.
9898

99-
In this section we will show how to implement http `post`, `put` and `delete` calls in `HeroService` to meet our new requirements.
99+
We'll complete `HeroService` by creating `post`, `put` and `delete` http calls to meet our new requirements.
100100

101101
:marked
102102
### Post
103103

104-
We are using `post` to add new `Hero` objects to our database. Post requests require a little bit more setup than Get requests, but the format is as follows:
104+
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:
105105

106106
+makeExample('toh-6/ts/app/hero.service.ts', 'post-hero', 'app/hero.service.ts (post hero)')(format=".")
107107

108108
:marked
109-
First we create a header and set the content type to `application/json`. Before posting we have to call `JSON.stringify` to convert the hero object to a string.
109+
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.
110110

111111
### Put
112112

@@ -121,12 +121,12 @@ code-example(format="." language="bash").
121121
+makeExample('toh-6/ts/app/hero.service.ts', 'delete-hero', 'app/hero.service.ts (delete hero)')(format=".")
122122

123123
:marked
124-
In all three cases we add a `catch` for error handling.
124+
We add a `catch` to handle our errors for all three cases.
125125

126126
:marked
127127
### Save
128128

129-
I am combining 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.
129+
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.
130130

131131
+makeExample('toh-6/ts/app/hero.service.ts', 'save', 'app/hero.service.ts (save hero)')(format=".")
132132

@@ -154,9 +154,9 @@ code-example(format="." language="bash").
154154
+makeExample('toh-6/ts/app/hero-detail.component.ts', 'save', 'app/hero-detail.component.ts (save)')(format=".")
155155

156156
:marked
157-
The same save method is used for both add end edit since `HeroService` will know when to call `post` vs `put` based on the state of the `Hero` object.
157+
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.
158158

159-
We mentioned earlier that `save()` returns a promise, so when the promise resolves, we call `emit` to notify `HeroesComponent` 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.
159+
Earlier we used the `save()` method to return a promise, so when the promise resolves, we call `emit` to notify `HeroesComponent` 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.
160160

161161
.l-sub-section
162162
:marked
@@ -185,7 +185,7 @@ figure.image-display
185185
:marked
186186
## Integration with Http
187187

188-
`Http` is not part of Angular core, but exists as a separate add-on module called `angular2/http`. It ships as a separate bundle, so we have to include the bundle in `index.html`.
188+
`Http` is not part of the Angular core module, but exists as a separate add-on module called `angular2/http`. It ships as a separate bundle, so we have to include the bundle in `index.html`.
189189

190190
+makeExample('toh-6/ts/index.html', 'http', 'index.html (http)')(format=".")
191191

@@ -196,13 +196,13 @@ figure.image-display
196196

197197
:marked
198198
### Simulating the api
199-
Our hero api is not deployed to production yet, but for the purposes of this chapter we have decided to integrate with an in-memory web api simulator.
199+
Our hero api is not deployed to production yet, but for the purposes of this chapter we have decided to integrate with an in-memory web api.
200200

201-
If you look at `AppComponent` you will notice that we have also imported `InMemoryBackendService`, `HeroData` and `SEED_DATA`. These imports are only there to configure the api simulator and will not be needed when integrating with a real api.
201+
Looking at the `AppComponent` we notice that we have also imported `InMemoryBackendService`, `InMemoryDataService` and `SEED_DATA`. These imports are only there to configure the in-memory web api and will not be needed when integrating with a real api.
202202

203-
We have included some more information about configuring the simulator <a href='/docs/ts/latest/guide/server-communication.html#!#in-mem-web-api'>here</a>.
203+
We have included some more information about configuring the in-memory web api <a href='/docs/ts/latest/guide/server-communication.html#!#in-mem-web-api'>here</a>.
204204

205-
Since we are integrating with the simulator we no longer need `mock-heroes.ts`, so it's safe to delete it.
205+
Since we are integrating with the in-memory web api we no longer need `mock-heroes.ts`, so it's safe to delete it.
206206

207207
:marked
208208
### Review the App Structure
@@ -227,7 +227,7 @@ figure.image-display
227227
.file heroes.component.html
228228
.file heroes.component.ts
229229
.file main.ts
230-
.file hero-data.ts
230+
.file hero-data.service.ts
231231
.file node_modules ...
232232
.file typings ...
233233
.file index.html
@@ -236,17 +236,33 @@ figure.image-display
236236
.file sample.css
237237
.file tsconfig.json
238238
.file typings.json
239-
240-
:marked
241-
242-
.l-main-section
239+
240+
.l-main-section
243241
:marked
244-
## Recap
242+
## Home Stretch
243+
244+
We are at the end of our journey for now, but we have accomplished a lot.
245+
- We added the necessary dependencies to use Http in our application.
246+
- We refactored HeroService to load heroes from an api.
247+
- We extended HeroService to support post, put and delete calls.
248+
- We updated our components to allow adding, editing and deleting of heroes.
249+
- We configured an in-memory web api.
250+
251+
Below is a summary of the files we changed.
252+
253+
+makeTabs(
254+
`toh-6/ts/app/app.component.ts,
255+
toh-6/ts/app/heroes.component.ts,
256+
toh-6/ts/app/heroes.component.html,
257+
toh-6/ts/app/hero-detail.component.ts,
258+
toh-6/ts/app/hero-detail.component.html,
259+
toh-6/ts/app/hero.service.ts`,
260+
null,
261+
`app.comp...ts,
262+
heroes.comp...ts,
263+
heroes.comp...html,
264+
hero-detail.comp...ts,
265+
hero-detail.comp...html,
266+
hero.service.ts`
267+
)
245268

246-
### The Road Behind
247-
We travelled a great distance in this chapter.
248-
- We add the necessary dependencies to use Http in our application.
249-
- We refactored HeroService to load heroes from a database.
250-
- We extended HeroService to support post, put and delete calls.
251-
- We updated our components to allow adding, editing and deleting of heroes.
252-
- We configured an in-memory api simulator.

0 commit comments

Comments
 (0)