+
+ Your interceptor should return every event without modification unless it has a compelling reason to do otherwise.
+
+
+
+TypeScript prevents you from setting `HttpRequest` read-only properties.
```javascript
// Typescript disallows the following assignment because req.url is readonly
req.url = req.url.replace('http://', 'https://');
```
-To alter the request, clone it first and modify the clone before passing it to `next.handle()`.
-You can clone and modify the request in a single step as in this example.
+
+If you must alter a request, clone it first and modify the clone before passing it to `next.handle()`.
+You can clone and modify the request in a single step, as shown in the following example.
+The _cache-then-refresh_ option is triggered by the presence of a custom `x-refresh` header.
+
A checkbox on the `PackageSearchComponent` toggles a `withRefresh` flag,
which is one of the arguments to `PackageSearchService.search()`.
That `search()` method creates the custom `x-refresh` header
@@ -778,128 +817,19 @@ and adds it to the request before calling `HttpClient.get()`.
The revised `CachingInterceptor` sets up a server request
whether there's a cached value or not,
using the same `sendRequest()` method described [above](#send-request).
-The `results$` observable will make the request when subscribed.
+The `results$` observable makes the request when subscribed.
-If there's no cached value, the interceptor returns `results$`.
+* If there's no cached value, the interceptor returns `results$`.
-If there is a cached value, the code _pipes_ the cached response onto
+* If there is a cached value, the code _pipes_ the cached response onto
`results$`, producing a recomposed observable that emits twice,
the cached response first (and immediately), followed later
by the response from the server.
-Subscribers see a sequence of _two_ responses.
+Subscribers see a sequence of two responses.
-### Configuring the request
+{@a report-progress}
-Other aspects of an outgoing request can be configured via the options object
-passed as the last argument to the `HttpClient` method.
-
-In [Adding headers](#adding-headers), the `HeroesService` set the default headers by
-passing an options object (`httpOptions`) to its save methods.
-You can do more.
-
-#### URL query strings
-
-In this section, you will see how to use the `HttpParams` class to add URL query strings in your `HttpRequest`.
-
-The following `searchHeroes` method queries for heroes whose names contain the search term.
-Start by importing `HttpParams` class.
-
-
-import {HttpParams} from "@angular/common/http";
-
-
-
-
-
-If there is a search term, the code constructs an options object with an HTML URL-encoded search parameter.
-If the term were "foo", the GET request URL would be `api/heroes?name=foo`.
-
-The `HttpParams` are immutable so you'll have to save the returned value of the `.set()` method in order to update the options.
-
-#### Use `fromString` to create HttpParams
-
-You can also create HTTP parameters directly from a query string by using the `fromString` variable:
-
-
-const params = new HttpParams({fromString: 'name=foo'});
-
-
-### Debouncing requests
-
-The sample includes an _npm package search_ feature.
-
-When the user enters a name in a search-box, the `PackageSearchComponent` sends
-a search request for a package with that name to the NPM web API.
-
-Here's a pertinent excerpt from the template:
-
-
-
-
-The `keyup` event binding sends every keystroke to the component's `search()` method.
-
-Sending a request for every keystroke could be expensive.
-It's better to wait until the user stops typing and then send a request.
-That's easy to implement with RxJS operators, as shown in this excerpt.
-
-
-
-
-The `searchText$` is the sequence of search-box values coming from the user.
-It's defined as an RxJS `Subject`, which means it is a multicasting `Observable`
-that can also emit values for itself by calling `next(value)`,
-as happens in the `search()` method.
-
-Rather than forward every `searchText` value directly to the injected `PackageSearchService`,
-the code in `ngOnInit()` _pipes_ search values through three operators:
-
-1. `debounceTime(500)` - wait for the user to stop typing (1/2 second in this case).
-
-2. `distinctUntilChanged()` - wait until the search text changes.
-
-3. `switchMap()` - send the search request to the service.
-
-The code sets `packages$` to this re-composed `Observable` of search results.
-The template subscribes to `packages$` with the [AsyncPipe](api/common/AsyncPipe)
-and displays search results as they arrive.
-
-A search value reaches the service only if it's a new value and the user has stopped typing.
-
-
-
-The `withRefresh` option is explained [below](#cache-refresh).
-
-
-
-#### _switchMap()_
-
-The `switchMap()` operator has three important characteristics.
-
-1. It takes a function argument that returns an `Observable`.
-`PackageSearchService.search` returns an `Observable`, as other data service methods do.
-
-2. If a previous search request is still _in-flight_ (as when the network connection is poor),
-it cancels that request and sends a new one.
-
-3. It returns service responses in their original request order, even if the
-server returns them out of order.
-
-
-
-If you think you'll reuse this debouncing logic,
-consider moving it to a utility function or into the `PackageSearchService` itself.
-
-
-
-### Listening to progress events
+## Tracking and showing request progress
Sometimes applications transfer large amounts of data and those transfers can take a long time.
File uploads are a typical example.
@@ -916,15 +846,15 @@ with the `reportProgress` option set true to enable tracking of progress events.
-Every progress event triggers change detection, so only turn them on if you truly intend to report progress in the UI.
+Every progress event triggers change detection, so only turn them on if you need to report progress in the UI.
-When using [`HttpClient#request()`](api/common/http/HttpClient#request) with an HTTP method, configure with
+When using [`HttpClient.request()`](api/common/http/HttpClient#request) with an HTTP method, configure with
[`observe: 'events'`](api/common/http/HttpClient#request) to see all events, including the progress of transfers.
Next, pass this request object to the `HttpClient.request()` method, which
-returns an `Observable` of `HttpEvents`, the same events processed by interceptors:
+returns an `Observable` of `HttpEvents` (the same events processed by [interceptors](#interceptor-events)).
+## Optimizing server interaction with debouncing
+
+If you need to make an HTTP request in response to user input, it's not efficient to send a request for every keystroke.
+It's better to wait until the user stops typing and then send a request.
+This technique is known as debouncing.
+
+Consider the following template, which lets a user enter a search term to find an npm package by name.
+When the user enters a name in a search-box, the `PackageSearchComponent` sends
+a search request for a package with that name to the npm web API.
+
+
+
+
+Here, the `keyup` event binding sends every keystroke to the component's `search()` method.
+The following snippet implements debouncing for this input using RxJS operators.
+
+
+
+
+The `searchText$` is the sequence of search-box values coming from the user.
+It's defined as an RxJS `Subject`, which means it is a multicasting `Observable`
+that can also emit values for itself by calling `next(value)`,
+as happens in the `search()` method.
+
+Rather than forward every `searchText` value directly to the injected `PackageSearchService`,
+the code in `ngOnInit()` pipes search values through three operators, so that a search value reaches the service only if it's a new value and the user has stopped typing.
+
+* `debounceTime(500)`&emdash;Wait for the user to stop typing (1/2 second in this case).
+
+* `distinctUntilChanged()`&emdash;Wait until the search text changes.
+
+* `switchMap()`&emdash;Send the search request to the service.
+
+The code sets `packages$` to this re-composed `Observable` of search results.
+The template subscribes to `packages$` with the [AsyncPipe](api/common/AsyncPipe)
+and displays search results as they arrive.
+
+
+
+See [Using interceptors to request multiple values](#cache-refresh) for more about the `withRefresh` option.
+
+
+
+### Using the *switchMap()* operator
+
+The `switchMap()` operator takes a function argument that returns an `Observable`.
+In the example, `PackageSearchService.search` returns an `Observable`, as other data service methods do.
+If a previous search request is still in-flight (as when the network connection is poor),
+the operator cancels that request and sends a new one.
+
+Note that `switchMap()` returns service responses in their original request order, even if the
+server returns them out of order.
+
+
+
+
+If you think you'll reuse this debouncing logic,
+consider moving it to a utility function or into the `PackageSearchService` itself.
+
+
+
+
## Security: XSRF protection
[Cross-Site Request Forgery (XSRF or CSRF)](https://en.wikipedia.org/wiki/Cross-site_request_forgery) is an attack technique by which the attacker can trick an authenticated user into unknowingly executing actions on your website.
@@ -985,6 +983,7 @@ use `HttpClientXsrfModule.withOptions()` to override the defaults.
region="xsrf">
+{@a testing-requests}
## Testing HTTP requests
As for any external dependency, you must mock the HTTP backend so your tests can simulate interaction with a remote server.
@@ -1008,7 +1007,7 @@ There are also tests of an application data service that call `HttpClient` in
-### Setup
+### Setup for testing
To begin testing calls to `HttpClient`,
import the `HttpClientTestingModule` and the mocking controller, `HttpTestingController`,
diff --git a/aio/content/navigation.json b/aio/content/navigation.json
index 6f50a13020..75d1ed547f 100644
--- a/aio/content/navigation.json
+++ b/aio/content/navigation.json
@@ -401,8 +401,13 @@
},
{
"url": "guide/http",
+<<<<<<< HEAD
"title": "Access Servers over HTTP",
"tooltip": "Use HTTP to talk to a remote server."
+=======
+ "title": "Server Interaction",
+ "tooltip": "Use HTTP to communicate with a remote server."
+>>>>>>> docs: update http guide
},
{
"url": "guide/router",