- var _example = 'toh-6';

block includes
  include ../_util-fns
  - var _Http = 'Http'; // Angular `Http` library name.
  - var _Angular_Http = 'Angular <code>Http</code>'
  - var _Angular_http_library = 'Angular HTTP library'
  - var _HttpModule = 'HttpModule'
  - var _JSON_stringify = 'JSON.stringify'

//- Shared var definitions
- var _promise = _Promise.toLowerCase()

:marked
  In this page, you'll make the following improvements.

  * Get the hero data from a server.
  * Let users add, edit, and delete hero names.
  * Save the changes to the server.

  You'll teach the app to make corresponding HTTP calls to a remote server's web API.

  When you're done with this page, the app should look like this <live-example></live-example>.

.l-main-section
:marked
  ## Where you left off

  In the [previous page](toh-pt5.html), you learned to navigate between the dashboard and the fixed heroes list,
  editing a selected hero along the way.
  That's the starting point for this page.
block start-server-and-watch
  :marked
    ## Keep the app transpiling and running
    Enter the following command in the terminal window:

code-example(language="sh" class="code-shell").
  npm start

:marked
  This command runs the TypeScript compiler in "watch mode", recompiling automatically when the code changes.
  The command simultaneously launches the app in a browser and refreshes the browser when the code changes.

  You can keep building the Tour of Heroes without pausing to recompile or refresh the browser.

.l-main-section#http-providers
h1 Providing HTTP Services
block http-library
  :marked
    The `HttpModule` is not a core Angular module.
    `HttpModule` is Angular's optional approach to web access. It exists as a separate add-on module called `@angular/http`
    and is shipped in a separate script file as part of the Angular npm package.

    You're ready to import from `@angular/http` because `systemjs.config` configured *SystemJS* to load that library when you need it.

:marked
  ### Register for HTTP services

block http-providers
  :marked
    The app will depend on the Angular `http` service, which itself depends on other supporting services.
    The `HttpModule` from the `@angular/http` library holds providers for a complete set of HTTP services.

    To allow access to these services from anywhere in the app,
    add `HttpModule` to the `imports` list of the `AppModule`.

  +makeExample('src/app/app.module.ts', 'v1','src/app/app.module.ts (v1)')

  :marked
    Notice that you also supply `!{_HttpModule}` as part of the *imports* !{_array} in root NgModule `AppModule`.

.l-main-section
:marked
  ## Simulate the web API

  We recommend registering app-wide services in the root
  `!{_AppModuleVsAppComp}` *providers*.  <span if-docs="dart">Here you're
  registering in `main` for a special reason.</span>

  Until you have a web server that can handle requests for hero data,
  the HTTP client will fetch and save data from
  a mock service, the *in-memory web API*.
  <span if-docs="dart"> The app itself doesn't need to know
  about this, so you can slip the in-memory web API into the
  configuration above the `AppComponent`.</span>

  Update <span ngio-ex>!{_appModuleTsVsMainTs}</span> with this version, which uses the mock service:

+makeExcerpt(_appModuleTsVsMainTs, 'v2')

block backend
  :marked
    Rather than require a real API server, this example simulates communication with the remote server by adding the
    <a href="https://github.com/angular/in-memory-web-api" target="_blank" title="In-memory Web API">InMemoryWebApiModule</a>
    to the module `imports`, effectively  replacing the `Http` client's XHR backend service with an in-memory alternative.

  +makeExcerpt(_appModuleTsVsMainTs, 'in-mem-web-api', '')

  :marked
    The `forRoot()` configuration method takes an `InMemoryDataService` class
    that primes the in-memory database.
    Add the file `in-memory-data.service.ts` in `!{_appDir}` with the following content:

+makeExample('src/app/in-memory-data.service.ts', 'init')(format='.')
:marked
  This file replaces `mock-heroes.ts`, which is now safe to delete.

block dont-be-distracted-by-backend-subst
  .alert.is-helpful
    :marked
      The in-memory web API is only useful in the early stages of development and for demonstrations such as this Tour of Heroes.
      Don't worry about the details of this backend substitution; you can
      skip it when you have a real web API server.

      Read more about the in-memory web API in the
      [Appendix: Tour of Heroes in-memory web api](../guide/server-communication.html#in-mem-web-api)
      section of the [HTTP Client](../guide/server-communication.html#in-mem-web-api) page.

.l-main-section
:marked
  ## Heroes and HTTP

  In the current `HeroService` implementation, a !{_Promise} resolved with mock heroes is returned.

+makeExcerpt('toh-4/ts/src/app/hero.service.ts (old getHeroes)', 'get-heroes')

:marked
  This was implemented in anticipation of ultimately
  fetching heroes with an HTTP client, which must be an asynchronous operation.

  Now convert `getHeroes()` to use HTTP.

+makeExcerpt('src/app/hero.service.ts (updated getHeroes and new class members)', 'getHeroes')

:marked
  Update the import statements as follows:

+makeExcerpt('src/app/hero.service.ts (updated imports)', 'imports')

- var _h3id = `http-${_promise}`
:marked
  Refresh the browser. The hero data should successfully load from the
  mock server.

  <h3 id="!{_h3id}">HTTP !{_Promise}</h3>


block get-heroes-details
  :marked
    The Angular `http.get` returns an RxJS `Observable`.
    *Observables* are a powerful way to manage asynchronous data flows.
    You'll read about [Observables](#observables) later in this page.

    For now, you've converted the `Observable` to a `Promise` using the `toPromise` operator.

  +makeExcerpt('src/app/hero.service.ts', 'to-promise', '')

  :marked
    The Angular `Observable` doesn't have a `toPromise` operator out of the box.

    There are many operators like `toPromise` that extend `Observable` with useful capabilities.
    To use those capabilities, you have to add the operators themselves.
    That's as easy as importing them from the RxJS library like this:

  +makeExcerpt('src/app/hero.service.ts', 'rxjs', '')

  .l-sub-section
    :marked
      You'll add more operators, and learn why you must do so, [later in this tutorial](#rxjs-imports).

  :marked
    ### Extracting the data in the *then* callback

    In the *Promise*'s `then()` callback, you call the `json` method of the HTTP `Response` to extract the
    data within the response.

  +makeExcerpt('src/app/hero.service.ts', 'to-data', '')

:marked
  The response JSON has a single `data` property, which
  holds the !{_array} of heroes that the caller wants.
  So you grab that !{_array} and return it as the resolved !{_Promise} value.

.alert.is-important
  :marked
    Note the shape of the data that the server returns.
    This particular in-memory web API example returns an object with a `data` property.
    Your API might return something else. Adjust the code to match your web API.

:marked
  The caller is unaware that you fetched the heroes from the (mock) server.
  It receives a !{_Promise} of *heroes* just as it did before.

  ### Error Handling

  At the end of `getHeroes()`, you `catch` server failures and pass them to an error handler.

+makeExcerpt('src/app/hero.service.ts', 'catch', '')

:marked
  This is a critical step.
  You must anticipate HTTP failures, as they happen frequently for reasons beyond your control.

+makeExcerpt('src/app/hero.service.ts', 'handleError', '')

- var rejected_promise = _docsFor == 'dart' ? 'propagated exception' : 'rejected promise';
:marked
  In this demo service, you log the error to the console; in real life,
  you would handle the error in code. For a demo, this works.

  The code also includes an error to
  the caller in a !{rejected_promise}, so that the caller can display a proper error message to the user.


  ### Get hero by id

  When the `HeroDetailComponent` asks the `HeroService` to fetch a hero,
  the `HeroService` currently fetches all heroes and
  filters for the one with the matching `id`.
  That's fine for a simulation, but it's wasteful to ask a real server for all heroes when you only want one.
  Most web APIs support a _get-by-id_ request in the form `api/hero/:id` (such as `api/hero/11`).

  Update the `HeroService.getHero` method to make a _get-by-id_ request:
+makeExcerpt('src/app/hero.service.ts', 'getHero', 'src/app/hero.service.ts')

:marked
  This request is almost the same as `getHeroes`.
  The hero id in the URL identifies which hero the server should update.

  Also, the `data` in the response is a single hero object rather than !{_an} !{_array}.

  ### Unchanged _getHeroes_ API

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

  Now it's time to add the ability to create and delete heroes.

.l-main-section
:marked
  ## Updating hero details

  Try editing a hero's name in the hero detail view.
  As you type, the hero name is updated in the view heading.
  But if you click the Back button, the changes are lost.

  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 you're fetching data
  from a server, if you want changes to persist, you must write them back to
  the server.

  ### Add the ability to save hero details

  At the end of the hero detail template, add a save button with a `click` event
  binding that invokes a new component method named `save`.

+makeExcerpt('src/app/hero-detail.component.html', 'save')

:marked
  Add the following `save` method, which persists hero name changes using the hero service
  `update` method and then navigates back to the previous view.

+makeExcerpt('src/app/hero-detail.component.ts', 'save')

:marked
  ### Add a hero service _update_ method

  The overall structure of the `update` method is similar to that of
  `getHeroes`, but it uses an HTTP `put()` to persist server-side changes.


+makeExcerpt('src/app/hero.service.ts', 'update')

:marked
  To identify which hero the server should update, the hero `id` is encoded in
  the URL. The `put()` body is the JSON string encoding of the hero, obtained by
  calling `!{_JSON_stringify}`. The body content type
  (`application/json`) is identified in the request header.

  Refresh the browser, change a hero name, save your change, 
  and click the browser Back button. Changes should now persist.

.l-main-section
:marked
  ## Add the ability to add heroes

  To add a hero, the app needs the hero's name. You can use an `input`
  element paired with an add button.

  Insert the following into the heroes component HTML, just after
  the heading:

+makeExcerpt('src/app/heroes.component.html', 'add')

:marked
  In response to a click event, call the component's click handler and then
  clear the input field so that it's ready for another name.

+makeExcerpt('src/app/heroes.component.ts', 'add')

:marked
  When the given name is non-blank, the handler delegates creation of the
  named hero to the hero service, and then adds the new hero to the !{_array}.

  Implement the `create` method in the `HeroService` class.
+makeExcerpt('src/app/hero.service.ts', 'create')

:marked
  Refresh the browser and create some heroes.

.l-main-section
:marked
  ## Add the ability to delete a hero

  Each hero in the heroes view should have a delete button.

  Add the following button element to the heroes component HTML, after the hero
  name in the repeated `<li>` tag.

+makeExcerpt('src/app/heroes.component.html', 'delete', '')

:marked
  The `<li>` element should now look like this:

+makeExcerpt('src/app/heroes.component.html', 'li-element')

:marked
  In addition to calling the component's `delete()` method, the delete button's
  click handler code stops the propagation of the click event&mdash;you
  don't want the `<li>` click handler to be triggered because doing so would
  select the hero that the user will delete.

  The logic of the `delete()` handler is a bit trickier:

+makeExcerpt('src/app/heroes.component.ts', 'delete')

:marked
  Of course you delegate hero deletion to the hero service, but the component
  is still responsible for updating the display: it removes the deleted hero
  from the !{_array} and resets the selected hero, if necessary.

:marked
  To place the delete button at the far right of the hero entry,
  add this additional CSS:

+makeExcerpt('src/app/heroes.component.css', 'additions')

:marked
  ### Hero service `delete()` method

  Add the hero service's `delete()` method, which uses the `delete()` HTTP method to remove the hero from the server:

+makeExcerpt('src/app/hero.service.ts', 'delete')

:marked
  Refresh the browser and try the new delete functionality.

#observables
:marked
  ## !{_Observable}s

block observables-section-intro
  :marked
    Each `Http` service method  returns an `Observable` of HTTP `Response` objects.

    The `HeroService` converts that `Observable` into a `Promise` and returns the promise to the caller.
    This section shows you how, when, and why to return the `Observable` directly.

    ### Background
    An *Observable* is a stream of events that you can process with array-like operators.

    Angular core has basic support for observables.
    Developers augment that support with operators and extensions from the
    <a href="http://reactivex.io/rxjs" target="_blank" title="RxJS">RxJS library</a>.
    You'll see how shortly.

    Recall that the `HeroService` chained the `toPromise` operator to the `Observable` result of `http.get()`.
    That operator converted the `Observable` into a `Promise` and you passed that promise back to the caller.

    Converting to a Promise is often a good choice. You typically ask `http.get()` to fetch a single chunk of data.
    When you receive the data, you're done.
    The calling component can easily consume a single result in the form of a Promise.

:marked
  But requests aren't always done only once.
  You may start one request,
  cancel it, and make a different request before the server has responded to the first request.
  A *request-cancel-new-request* sequence is difficult to implement with *!{Promise}s*, but
  easy with *!{Observable}s*.

  ### Add the ability to search by name
  You're going to add a *hero search* feature to the Tour of Heroes.
  As the user types a name into a search box, you'll make repeated HTTP requests for heroes filtered by that name.

  Start by creating `HeroSearchService` that sends search queries to the server's web API.

+makeExample('src/app/hero-search.service.ts')

:marked
  The `!{_priv}http.get()` call in `HeroSearchService` is similar to the one
  in the `HeroService`, although the URL now has a query string.

  <span if-docs="ts">More importantly, you no longer call `toPromise()`.
  Instead you return the *Observable* from the the `htttp.get()`,
  after chaining it to another RxJS operator, <code>map()</code>,
  to extract heroes from the response data.

  RxJS operator chaining makes response processing easy and readable.
  See the [discussion below about operators](#rxjs-imports).

:marked
  ### HeroSearchComponent

  Create a `HeroSearchComponent` that calls the new `HeroSearchService`.

  The component template is simple&mdash;just a text box and a list of matching search results.

+makeExample('src/app/hero-search.component.html')
:marked
  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 expected, the `*ngFor` repeats hero objects from the component's `heroes` property.

  But as you'll soon see, the `heroes` property is now !{_an} *!{_Observable}* of hero !{_array}s, rather than just a hero !{_array}.
  The `*ngFor` can't do anything with !{_an} `!{_Observable}` until you route it through the `async` pipe (`AsyncPipe`).
  The `async` pipe subscribes to the `!{_Observable}` and produces the !{_array} of heroes to `*ngFor`.

  Create the `HeroSearchComponent` class and metadata.

+makeExample('src/app/hero-search.component.ts')

:marked
  #### Search terms

  Focus on the `!{_priv}searchTerms`:

+makeExcerpt('src/app/hero-search.component.ts', 'searchTerms', '')

block search-criteria-intro
  :marked
    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()`.

:marked
  <a id="ngoninit"></a>
  #### Initialize the *heroes* property (*ngOnInit*)

  <span if-docs="ts">A `Subject` is also an `Observable`.</span>
  You can turn the stream
  of search terms into a stream of `Hero` !{_array}s and assign the result to the `heroes` property.

+makeExcerpt('src/app/hero-search.component.ts', 'search', '')

:marked
  Passing every user keystroke directly to the `HeroSearchService` would create an excessive amount of HTTP requests,
  taxing server resources and burning through the cellular network data plan.

block observable-transformers
  :marked
    Instead, you can chain `Observable` operators that reduce the request flow to the string `Observable`.
    You'll make fewer calls to the `HeroSearchService` and still get timely results. Here's how:

    * `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`.
    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.
      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
       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
      and an observable containing an empty array is returned.

      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
    * `catch` intercepts a failed observable.
    The simple example prints the error to the console; a real life app would do better.
    Then to clear the search result, you return an observable containing an empty array.

  a#rxjs-imports
  :marked
    ### Import RxJS operators

    Most RxJS operators are not included in Angular's base `Observable` implementation.
    The base implementation includes only what Angular itself requires.

    When you need more RxJS features, extend  `Observable` by *importing* the libraries in which they are defined.
    Here are all the RxJS imports that _this_ component needs:

  +makeExample('src/app/hero-search.component.ts','rxjs-imports','src/app/hero-search.component.ts (rxjs imports)')(format='.')

  :marked
    The `import 'rxjs/add/...'` syntax may be unfamiliar.
    It's missing the usual list of symbols between the braces: `{...}`.

    You don't need the operator symbols themselves.
    In each case, the mere act of importing the library
    loads and executes the library's script file which, in turn, adds the operator to the `Observable` class.

:marked
  ### Add the search component to the dashboard

  Add the hero search HTML element to the bottom of the `DashboardComponent` template.

+makeExample('src/app/dashboard.component.html')(format='.')

- var _declarations = _docsFor == 'dart' ? 'directives' : 'declarations'
- var declFile = _docsFor == 'dart' ? 'src/app/dashboard.component.ts' : 'src/app/app.module.ts'
:marked
  Finally, import `HeroSearchComponent` from
  <span ngio-ex>hero-search.component.ts</span>
  and add it to the `!{_declarations}` !{_array}.

+makeExcerpt(declFile, 'search')

:marked
  Run the app again. In the Dashboard, enter some text in the search box.
  If you enter characters that match any existing hero names, you'll see something like this.

figure.image-display
  img(src='/resources/images/devguide/toh/toh-hero-search.png' alt="Hero Search Component")

.l-main-section
:marked
  ## App structure and code

  Review the sample source code in the <live-example></live-example> for this page.
  Verify that you have the following structure:

block filetree
  .filetree
    .file angular-tour-of-heroes
    .children
      .file src
      .children
        .file app
        .children
          .file app.component.ts
          .file app.component.css
          .file app.module.ts
          .file app-routing.module.ts
          .file dashboard.component.css
          .file dashboard.component.html
          .file dashboard.component.ts
          .file hero.ts
          .file hero-detail.component.css
          .file hero-detail.component.html
          .file hero-detail.component.ts
          .file hero-search.component.html (new)
          .file hero-search.component.css (new)
          .file hero-search.component.ts (new)
          .file hero-search.service.ts (new)
          .file hero.service.ts
          .file heroes.component.css
          .file heroes.component.html
          .file heroes.component.ts
          .file in-memory-data.service.ts (new)
        .file main.ts
        .file index.html
        .file styles.css
        .file systemjs.config.js
        .file tsconfig.json
      .file node_modules ...
      .file package.json

.l-main-section
:marked
  ## Home Stretch

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

  Here are the files you added or changed in this page.

block file-summary
  +makeTabs(
    `toh-6/ts/src/app/app.component.ts,
     toh-6/ts/src/app/app.module.ts,
     toh-6/ts/src/app/heroes.component.ts,
     toh-6/ts/src/app/heroes.component.html,
     toh-6/ts/src/app/heroes.component.css,
     toh-6/ts/src/app/hero-detail.component.ts,
     toh-6/ts/src/app/hero-detail.component.html,
     toh-6/ts/src/app/hero.service.ts,
     toh-6/ts/src/app/in-memory-data.service.ts`,
    ',,,,,,,,',
    `app.comp...ts,
     app.mod...ts,
     heroes.comp...ts,
     heroes.comp...html,
     heroes.comp...css,
     hero-detail.comp...ts,
     hero-detail.comp...html,
     hero.service.ts,
     in-memory-data.service.ts`
  )

  +makeTabs(
    `toh-6/ts/src/app/hero-search.service.ts,
    toh-6/ts/src/app/hero-search.component.ts,
    toh-6/ts/src/app/hero-search.component.html,
    toh-6/ts/src/app/hero-search.component.css`,
    null,
    `hero-search.service.ts,
    hero-search.component.ts,
    hero-search.component.html,
    hero-search.component.css`
  )

.l-sub-section
  :marked
    ## Next step

    Return to the [learning path](../guide/learning-angular.html#architecture), where
    you can read more about the concepts and practices found in this tutorial.
