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

docs(toh-6/dart): getHero makes HTTP get-by-id #2936

Merged
merged 1 commit into from
Dec 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions public/docs/_examples/toh-6/dart/lib/hero_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class HeroService {
static final _headers = {'Content-Type': 'application/json'};
// #enddocregion update
// #docregion getHeroes
static const _heroesUrl = 'app/heroes'; // URL to web API
static const _heroesUrl = 'api/heroes'; // URL to web API

final Client _http;

Expand Down Expand Up @@ -46,8 +46,16 @@ class HeroService {
}
// #enddocregion handleError, getHeroes

Future<Hero> getHero(int id) async =>
(await getHeroes()).firstWhere((hero) => hero.id == id);
// #docregion getHero
Future<Hero> getHero(int id) async {
try {
final response = await _http.get('$_heroesUrl/$id');
return new Hero.fromJson(_extractData(response));
} catch (e) {
throw _handleError(e);
}
}
// #enddocregion getHero

// #docregion create
Future<Hero> create(String name) async {
Expand All @@ -64,7 +72,7 @@ class HeroService {

Future<Hero> update(Hero hero) async {
try {
var url = '$_heroesUrl/${hero.id}';
final url = '$_heroesUrl/${hero.id}';
final response =
await _http.put(url, headers: _headers, body: JSON.encode(hero));
return new Hero.fromJson(_extractData(response));
Expand All @@ -77,7 +85,7 @@ class HeroService {
// #docregion delete
Future<Null> delete(int id) async {
try {
var url = '$_heroesUrl/$id';
final url = '$_heroesUrl/$id';
await _http.delete(url, headers: _headers);
} catch (e) {
throw _handleError(e);
Expand Down
11 changes: 8 additions & 3 deletions public/docs/_examples/toh-6/dart/lib/in_memory_data_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,14 @@ class InMemoryDataService extends MockClient {
var data;
switch (request.method) {
case 'GET':
String prefix = request.url.queryParameters['name'] ?? '';
final regExp = new RegExp(prefix, caseSensitive: false);
data = _heroesDb.where((hero) => hero.name.contains(regExp)).toList();
final id = int.parse(request.url.pathSegments.last, onError: (_) => null);
if (id != null) {
data = _heroesDb.firstWhere((hero) => hero.id == id); // throws if no match
} else {
String prefix = request.url.queryParameters['name'] ?? '';
final regExp = new RegExp(prefix, caseSensitive: false);
data = _heroesDb.where((hero) => hero.name.contains(regExp)).toList();
}
break;
// #enddocregion init-disabled
case 'POST':
Expand Down
41 changes: 29 additions & 12 deletions public/docs/ts/_cache/tutorial/toh-pt6.jade
Original file line number Diff line number Diff line change
Expand Up @@ -212,12 +212,32 @@ block get-heroes-details
We've also decided to return a user friendly form of the error to
the caller in a !{rejected_promise} so that the caller can display a proper error message to the user.

### Unchanged `getHeroes` API
### Get hero by id
The `HeroDetailComponent` asks the `HeroService` to fetch a single hero to edit.

The `HeroService` currently fetches all heroes and then finds the desired hero
by filtering for the one with the matching `id`.
That's fine in a simulation. It's wasteful to ask a real server for _all_ heroes when we only want one.
Most web APIs support a _get-by-id_ request in the form `api/hero/:id` (e.g., `api/hero/11`).

Although we made significant *internal* changes to `getHeroes()`, the public signature did not change.
We still return a !{_Promise}. We won't have to update any of the components that call `getHeroes()`.
Update the `HeroService.getHero` method to make a _get-by-id_ request,
applying what we just learned to write `getHeroes`:
+makeExcerpt('app/hero.service.ts', 'getHero', '')
:marked
It's almost the same as `getHeroes`.
The URL identifies _which_ hero the server should update by encoding the hero id into the URL
to match the `api/hero/:id` pattern.

We also adjust to the fact that the `data` in the response is a single hero object rather than !{_an} !{_array}.

### Unchanged _getHeroes_ API

Although we made significant *internal* changes to `getHeroes()` and `getHero()`,
the public signatures did not change.
We still return a !{_Promise} from both methods.
We won't have to update any of the components that call them.

Our stakeholders are thrilled with the added flexibility from the API integration.
Our stakeholders are thrilled with the web API integration so far.
Now they want the ability to create and delete heroes.

Let's see first what happens when we try to update a hero's details.
Expand All @@ -230,15 +250,12 @@ block get-heroes-details
it. As we type, the hero name is updated in the view heading.
But when we hit the `Back` button, the changes are lost!

.l-sub-section
:marked
Updates weren't lost before, what's happening?
When the app used a list of mock heroes, changes were made directly to the
hero objects in the single, app-wide shared list. Now that we are fetching data
from a server, if we want changes to persist, we'll need to write them back to
the server.
Updates weren't lost before. What changed?
When the app used a list of mock heroes, updates were applied directly to the
hero objects within the single, app-wide, shared list. Now that we are fetching data
from a server, if we want changes to persist, we'll need to write them back to
the server.

:marked
### Save hero details

Let's ensure that edits to a hero's name aren't lost. Start by adding,
Expand Down
2 changes: 1 addition & 1 deletion public/docs/ts/latest/tutorial/toh-pt6.jade
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ block get-heroes-details
The URL identifies _which_ hero the server should update by encoding the hero id into the URL
to match the `api/hero/:id` pattern.

We also adjust to the fact that the `data` in the response is a single hero object rather than array.
We also adjust to the fact that the `data` in the response is a single hero object rather than !{_an} !{_array}.

### Unchanged _getHeroes_ API

Expand Down