@@ -131,7 +131,7 @@ block get-heroes-details
131131 :marked
132132 The Angular `http.get` returns an RxJS `Observable`.
133133 *Observables* are a powerful way to manage asynchronous data flows.
134- We'll learn about ` Observables` * later* .
134+ We'll learn about [ Observables](#observables) later in this chapter .
135135
136136 For *now* we get back on familiar ground by immediately converting that `Observable` to a `Promise` using the `toPromise` operator.
137137 + makeExample('toh-6/ts/app/hero.service.ts' , 'to-promise' )( format ="." )
@@ -361,41 +361,69 @@ block review
361361:marked
362362 ## Observables
363363
364- In this section we discuss `Observables` as an alternative to promises when processing http calls .
364+ Each `Http` method returns an `Observable` of HTTP `Response` objects .
365365
366- `Http` calls return RxJS observables by default, but so far we've been hiding that by converting the observable to a promise by calling `toPromise`.
366+ Our `HeroService` converts that `Observable` into a `Promise` and returns the promise to the caller.
367+ In this section we learn to return the `Observable` directly and discuss when and why that might be
368+ a good thing to do.
367369
368- Observables and promises are both great for processing http calls, but as we will see, the observables api is much richer.
370+ ### Background
371+ An *observable* is a stream of events that we can process with array-like operators.
369372
370- `RxJs` offers a wide variety of operators that we can use to manage event flows.
373+ Angular core has basic support for observables. We developers augment that support with
374+ operators and extensions from the [RxJS Observables](http://reactivex.io/rxjs/) library.
375+ We'll see how shortly.
371376
372- In this section we will discuss how to use some of these operators to build a type-to-search filter where we can search for heroes by name.
377+ Recall that our `HeroService` quickly chained the `toPromise` operator to the `Observable` result of `http.get`.
378+ That operator converted the `Observable` into a `Promise` and we passed that promise back to the caller.
379+
380+ Converting to a promise is often a good choice. We typically ask `http` to fetch a single chunk of data.
381+ When we receive the data, we're done.
382+ A single result in the form of a promise is easy for the calling component to consume
383+ and it helps that promises are widely understood by JavaScript programmers.
384+
385+ But requests aren't always "one and done". We may start one request,
386+ then cancel it, and make a different request ... before the server has responded to the first request.
387+ Such a _request-cancel-new-request_ sequence is difficult to implement with *promises*.
388+ It's easy with *observables* as we'll see.
389+
390+ ### Search-by-name example
391+ We're going to add a *hero search* feature to the Tour of Heroes.
392+ As the user types a name into a search box, we'll make repeated http requests for heroes filtered by that name.
373393
374- We start by creating `HeroSearchService`, a simple service for sending search queries to our api.
394+ We start by creating `HeroSearchService` that sends search queries to our server's web api.
375395
376396+ makeExample('toh-6/ts/app/hero-search.service.ts' , null , 'app/hero-search.service.ts' )( format ="." )
377397
378398:marked
379- The http call in `HeroSearchService` is not that different from our previous http calls, but we no longer call `toPromise`. This means we will return an observable instead of a promise.
399+ The `http.get` call in `HeroSearchService` is similar to the `http.get` call in the `HeroService`.
400+ The notable difference: we no longer call `toPromise`.
401+ We simply return the *observable* instead.
380402
381- Now, let's implement our search component `HeroSearchComponent`.
382-
383- + makeTabs(
384- ` toh-6/ts/app/hero-search.component.ts,
385- toh-6/ts/app/hero-search.component.html` ,
386- null ,
387- ` hero-search.component.ts,
388- hero-search.component.html`
389- )
403+ ### HeroSearchComponent
404+ Let's create a new `HeroSearchComponent` that calls this new `HeroSearchService`.
390405
406+ The component template is simple - just a textbox and a list of matching search results.
407+ + makeExample('toh-6/ts/app/hero-search.component.html' , null ,'hero-search.component.html' )
391408:marked
392- The `HeroSearchComponent` UI is simple - just a textbox and a list of matching search results.
393-
394- To keep track of text changes in the search box we are using an RxJs `Subject`.
409+ As the user types in the search box, a *keyup* event binding calls `search.next` with the new search box value.
395410
396- Observables are great for managing event streams. In our example we will actually be dealing with two different types of event streams:
411+ The componen'ts data bound `search` property returns a `Subject`.
412+ A `Subject` is a producer of an _observable_ event stream.
413+ Each call to `search.next` puts a new string into this subject's _observable_ stream.
414+
415+ Create a `HeroSearchComponent` as follows.
416+ + makeExample('toh-6/ts/app/hero-search.component.ts' , null ,'hero-search.component.ts' )
417+ :marked
418+ Scroll down to where we create the `search` subject.
419+ + makeExample('toh-6/ts/app/hero-search.component.ts' , 'subject' )
420+ :marked
421+ We're binding to that `search` subject in our template.
422+ The user is sending it a stream of strings, the filter criteria for the name search.
397423
398- 1) Key events from typing into the search textbox
424+ A `Subject` is also an `Observable`.
425+ We're going to access that `Observable` and add operators to that turn the stream
426+ of filter strings into a stream of http search results.
399427
400428 2) Results from http calls based on values entered in the search textbox
401429
@@ -539,4 +567,4 @@ block file-summary
539567 hero-search.component.ts,
540568 hero-search.service.html,
541569 rxjs-operators.ts`
542- )
570+ )
0 commit comments