Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: update text around changed obs examples #22920

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
32 changes: 13 additions & 19 deletions aio/content/guide/http.md
Expand Up @@ -295,7 +295,7 @@ to every `HttpClient` save method.
### Making a POST request

Apps often POST data to a server. They POST when submitting a form.
In the following example, the `HeroService` posts when adding a hero to the database.
In the following example, the `HeroesService` posts when adding a hero to the database.

<code-example
path="http/src/app/heroes/heroes.service.ts"
Expand All @@ -313,7 +313,6 @@ It takes two more parameters:
1. `httpOptions` - the method options which, in this case, [specify required headers](#adding-headers).

Of course it catches errors in much the same manner [described above](#error-details).
It also _taps_ the returned observable in order to log the successful POST.

The `HeroesComponent` initiates the actual POST operation by subscribing to
the `Observable` returned by this service method.
Expand Down Expand Up @@ -347,26 +346,22 @@ the `Observable` returned by this service method.
title="app/heroes/heroes.component.ts (deleteHero)" linenums="false">
</code-example>

The component isn't expecting a result from the delete operation, so it subscribes without a callback. Even though you are not using the result, you still have to subscribe. Calling the `subscribe()` method _executes_ the observable, which is what initiates the DELETE request.

<div class="alert is-important">

You must call _subscribe()_ or nothing happens!
You must call _subscribe()_ or nothing happens. Just calling `HeroesService.deleteHero()` **does not initiate the DELETE request.**

</div>

The component isn't expecting a result from the delete operation and
subscribes without a callback.
The bare `.subscribe()` _seems_ pointless.

In fact, it is essential.
Merely calling `HeroService.deleteHero()` **does not initiate the DELETE request.**

<code-example
path="http/src/app/heroes/heroes.component.ts"
region="delete-hero-no-subscribe" linenums="false">
</code-example>

{@a always-subscribe}
### Always _subscribe_!
**Always _subscribe_!**

An `HttpClient` method does not begin its HTTP request until you call `subscribe()` on the observable returned by that method. This is true for _all_ `HttpClient` _methods_.

Expand All @@ -378,8 +373,7 @@ The [`AsyncPipe`](api/common/AsyncPipe) subscribes (and unsubscribes) for you au

All observables returned from `HttpClient` methods are _cold_ by design.
Execution of the HTTP request is _deferred_, allowing you to extend the
observable with additional operations such as `tap` and `catchError`
before anything actually happens.
observable with additional operations such as `tap` and `catchError` before anything actually happens.

Calling `subscribe(...)` triggers execution of the observable and causes
`HttpClient` to compose and send the HTTP request to the server.
Expand All @@ -404,7 +398,7 @@ req.subscribe();
### Making a PUT request

An app will send a PUT request to completely replace a resource with updated data.
The following `HeroService` example is just like the POST example.
The following `HeroesService` example is just like the POST example.

<code-example
path="http/src/app/heroes/heroes.service.ts"
Expand All @@ -417,14 +411,14 @@ in order to initiate the request.

## Advanced usage

The above sections detail how to use the basic HTTP functionality in `@angular/common/http`, but sometimes you need to do more than make simple requests and get data back.
We have discussed the basic HTTP functionality in `@angular/common/http`, but sometimes you need to do more than make simple requests and get data back.

### Configuring the request

Other aspects of an outgoing request can be configured via the options object
passed as the last argument to the `HttpClient` method.

You [saw earlier](#adding-headers) that the `HeroService` sets the default headers by
You [saw earlier](#adding-headers) that the `HeroesService` sets the default headers by
passing an options object (`httpOptions`) to its save methods.
You can do more.

Expand Down Expand Up @@ -454,7 +448,7 @@ Here is a `searchHeroes` method that queries for heroes whose names contain the
region="searchHeroes" linenums="false">
</code-example>

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`.
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 `HttpParms` are immutable so you'll have to use the `set()` method to update the options.

Expand All @@ -463,7 +457,7 @@ The `HttpParms` are immutable so you'll have to use the `set()` method to update
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.
a search request for a package with that name to the NPM web API.

Here's a pertinent excerpt from the template:

Expand All @@ -486,7 +480,7 @@ That's easy to implement with RxJS operators, as shown in this excerpt.
</code-example>

The `searchText$` is the sequence of search-box values coming from the user.
It's defined as an RxJS `Subject`, which means it is an `Observable`
It's defined as an RxJS `Subject`, which means it is a multicasting `Observable`
that can also produce values for itself by calling `next(value)`,
as happens in the `search()` method.

Expand Down Expand Up @@ -820,7 +814,7 @@ Some folks describe it as a "_one and done_" observable.
But an interceptor can change this to an _observable_ that emits more than once.

A revised version of the `CachingInterceptor` optionally returns an _observable_ that
immediately emits the cached response, sends the request to the npm web api anyway,
immediately emits the cached response, sends the request to the NPM web API anyway,
and emits again later with the updated search results.

<code-example
Expand Down
3 changes: 1 addition & 2 deletions aio/content/guide/reactive-forms.md
Expand Up @@ -940,8 +940,7 @@ with that hero's data values.

A refresh button clears the hero list and the current selected hero before refetching the heroes.

Notice that `hero-list.component.ts` imports `Observable` and `finally` while `hero.service.ts` imports `Observable`, `of`,
and `delay` from `rxjs`.
Notice that `hero-list.component.ts` imports `Observable` and the `finalize` operator, while `hero.service.ts` imports `Observable`, `of`, and the `delay` operator from `rxjs`.

The remaining `HeroListComponent` and `HeroService` implementation details are beyond the scope of this tutorial.
However, the techniques involved are covered elsewhere in the documentation, including the _Tour of Heroes_
Expand Down
27 changes: 12 additions & 15 deletions aio/content/guide/router.md
Expand Up @@ -340,9 +340,9 @@ It has a great deal of useful information including:

Two older properties are still available. They are less capable than their replacements, discouraged, and may be deprecated in a future Angular version.

**`params`** &mdash; An `Observable` that contains the required and [optional parameters](#optional-route-parameters) specific to the route. Use `paramMap` instead.
**`params`**&mdash;An `Observable` that contains the required and [optional parameters](#optional-route-parameters) specific to the route. Use `paramMap` instead.

**`queryParams`** &mdash; An `Observable` that contains the [query parameters](#query-parameters) available to all routes.
**`queryParams`**&mdash;An `Observable` that contains the [query parameters](#query-parameters) available to all routes.
Use `queryParamMap` instead.

</div>
Expand Down Expand Up @@ -1619,8 +1619,7 @@ They are distributed across two modules, `AppRoutingModule` and `HeroesRoutingMo
Each routing module augments the route configuration _in the order of import_.
If you list `AppRoutingModule` first, the wildcard route will be registered
_before_ the hero routes.
The wildcard route &mdash; which matches _every_ URL &mdash;
will intercept the attempt to navigate to a hero route.
The wildcard route&mdash;which matches _every_ URL&mdash;will intercept the attempt to navigate to a hero route.


<div class="l-sub-section">
Expand Down Expand Up @@ -2060,7 +2059,7 @@ The path for the "Heroes" route doesn't have an `:id` token.

The optional route parameters are not separated by "?" and "&" as they would be in the URL query string.
They are **separated by semicolons ";"**
This is *matrix URL* notation &mdash; something you may not have seen before.
This is *matrix URL* notation&mdash;something you may not have seen before.


<div class="l-sub-section">
Expand Down Expand Up @@ -3149,7 +3148,7 @@ Here's a demo `AuthService`:
Although it doesn't actually log in, it has what you need for this discussion.
It has an `isLoggedIn` flag to tell you whether the user is authenticated.
Its `login` method simulates an API call to an external service by returning an
Observable that resolves successfully after a short pause.
observable that resolves successfully after a short pause.
The `redirectUrl` property will store the attempted URL so you can navigate to it after authenticating.

Revise the `AuthGuard` to call it.
Expand Down Expand Up @@ -3459,13 +3458,11 @@ Be explicit. Implement the `Resolve` interface with a type of `Crisis`.
Inject the `CrisisService` and `Router` and implement the `resolve()` method.
That method could return a `Promise`, an `Observable`, or a synchronous return value.

The `CrisisService.getCrisis` method returns an Observable.
Return that observable to prevent the route from loading until the data is fetched.
The `Router` guards require an Observable to `complete`, meaning it has emitted all
The `CrisisService.getCrisis` method returns an observable, in order to prevent the route from loading until the data is fetched.
The `Router` guards require an observable to `complete`, meaning it has emitted all
of its values. You use the `take` operator with an argument of `1` to ensure that the
Observable completes after retrieving the first value from the Observable returned by the
`getCrisis` method.
If it doesn't return a valid `Crisis`, navigate the user back to the `CrisisListComponent`,
observable completes after retrieving the first value from the observable returned by the
`getCrisis` method. If it doesn't return a valid `Crisis`, navigate the user back to the `CrisisListComponent`,
canceling the previous in-flight navigation to the `CrisisDetailComponent`.

Import this resolver in the `crisis-center-routing.module.ts`
Expand Down Expand Up @@ -3502,8 +3499,8 @@ The router looks for that method and calls it if found.
Don't worry about all the ways that the user could navigate away.
That's the router's job. Write this class and let the router take it from there.

1. The Observable provided to the Router _must_ complete.
If the Observable does not complete, the navigation will not continue.
1. The observable provided to the Router _must_ complete.
If the observable does not complete, the navigation will not continue.

The relevant *Crisis Center* code for this milestone follows.

Expand Down Expand Up @@ -3928,7 +3925,7 @@ The router calls the `preload` method with two arguments:
1. The route to consider.
1. A loader function that can load the routed module asynchronously.

An implementation of `preload`must return an `Observable`.
An implementation of `preload` must return an `Observable`.
If the route should preload, it returns the observable returned by calling the loader function.
If the route should _not_ preload, it returns an `Observable` of `null`.

Expand Down
24 changes: 11 additions & 13 deletions aio/content/guide/testing.md
Expand Up @@ -262,13 +262,12 @@ test any service with a dependency.

<div class="alert is-important">

The `HeroService` methods return _Observables_.
_Subscribe_ to the method observable to (a) cause it to execute and (b)
The `HeroService` methods return `Observables`. You must
_subscribe_ to an observable to (a) cause it to execute and (b)
assert that the method succeeds or fails.

The `subscribe()` method takes a success and fail callback.
Make sure you provide _both_ callbacks so that you capture errors.

The `subscribe()` method takes a success (`next`) and fail (`error`) callback.
Make sure you provide _both_ callbacks so that you capture errors.
Neglecting to do so produces an asynchronous uncaught observable error that
the test runner will likely attribute to a completely different test.

Expand Down Expand Up @@ -1024,9 +1023,9 @@ Focus on the spy.
region="spy">
</code-example>

The spy is designed such that any call to `getQuote` receives an Observable with a test quote.
The spy is designed such that any call to `getQuote` receives an observable with a test quote.
Unlike the real `getQuote()` method, this spy bypasses the server
and returns a synchronous Observable whose value is available immediately.
and returns a synchronous observable whose value is available immediately.

You can write many useful tests with this spy, even though its `Observable` is synchronous.

Expand Down Expand Up @@ -1114,14 +1113,14 @@ Or you can copy this one from the sample code.

This helper's observable emits the `data` value in the next turn of the JavaScript engine.

[RxJS `defer()`](http://reactivex.io/documentation/operators/defer.html) returns an observable.
The [RxJS `defer()` operator](http://reactivex.io/documentation/operators/defer.html) returns an observable.
It takes a factory function that returns either a promise or an observable.
When something subscribes to _defer_'s observable,
it adds the subscriber to a new observable created with that factory.

RxJS `defer()` transform the `Promise.resolve()` into a new observable that,
The `defer()` operator transforms the `Promise.resolve()` into a new observable that,
like `HttpClient`, emits once and completes.
Subscribers will be unsubscribed after they receive the data value.
Subscribers are unsubscribed after they receive the data value.

There's a similar helper for producing an async error.

Expand Down Expand Up @@ -1688,10 +1687,9 @@ Here's the `HeroDetailComponent` constructor:
<code-example path="testing/src/app/hero/hero-detail.component.ts" region="ctor" title="app/hero/hero-detail.component.ts (constructor)" linenums="false"></code-example>

The `HeroDetail` component needs the `id` parameter so it can fetch
the corresponding hero via the `HeroDetailService`.

the corresponding hero via the `HeroDetailService`.
The component has to get the `id` from the `ActivatedRoute.paramMap` property
which is an _Observable_.
which is an `Observable`.

It can't just reference the `id` property of the `ActivatedRoute.paramMap`.
The component has to _subscribe_ to the `ActivatedRoute.paramMap` observable and be prepared
Expand Down
6 changes: 3 additions & 3 deletions aio/content/guide/upgrade.md
Expand Up @@ -1342,7 +1342,7 @@ and the other loads the details of a specified phone:
<code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.ts" region="fullclass" title="app/core/phone/phone.service.ts">
</code-example>

The methods now return Observables of type `PhoneData` and `PhoneData[]`. This is
The methods now return observables of type `PhoneData` and `PhoneData[]`. This is
a type you don't have yet. Add a simple interface for it:

<code-example path="upgrade-phonecat-2-hybrid/app/core/phone/phone.service.ts" region="phonedata-interface" title="app/core/phone/phone.service.ts (interface)" linenums="false">
Expand Down Expand Up @@ -1385,14 +1385,14 @@ it's really an instance of the `Phone` class and you annotate its type according

Now there are two AngularJS components using an Angular service!
The components don't need to be aware of this, though the fact that the
service returns Observables and not Promises is a bit of a giveaway.
service returns observables and not promises is a bit of a giveaway.
In any case, what you've achieved is a migration of a service to Angular
without having to yet migrate the components that use it.

<div class="alert is-helpful">

You could use the `toPromise` method of `Observable` to turn those
Observables into Promises in the service. In many cases that reduce
observables into promises in the service. In many cases that reduce
the number of changes to the component controllers.

</div>
Expand Down
2 changes: 1 addition & 1 deletion aio/content/tutorial/toh-pt4.md
Expand Up @@ -446,7 +446,7 @@ Here are the code files discussed on this page and your app should look like thi
* You used [Angular Dependency Injection](guide/dependency-injection) to inject it into a component.
* You gave the `HeroService` _get data_ method an asynchronous signature.
* You discovered `Observable` and the RxJS _Observable_ library.
* You used RxJS `of()` to return an _Observable_ of mock heroes (`Observable<Hero[]>`).
* You used RxJS `of()` to return an observable of mock heroes (`Observable<Hero[]>`).
* The component's `ngOnInit` lifecycle hook calls the `HeroService` method, not the constructor.
* You created a `MessageService` for loosely-coupled communication between classes.
* The `HeroService` injected into a component is created with another injected service,
Expand Down
12 changes: 6 additions & 6 deletions aio/content/tutorial/toh-pt6.md
Expand Up @@ -145,8 +145,8 @@ All `HttpClient` methods return an RxJS `Observable` of something.
HTTP is a request/response protocol.
You make a request, it returns a single response.

In general, an `Observable` _can_ return multiple values over time.
An `Observable` from `HttpClient` always emits a single value and then completes, never to emit again.
In general, an observable _can_ return multiple values over time.
An observable from `HttpClient` always emits a single value and then completes, never to emit again.

This particular `HttpClient.get` call returns an `Observable<Hero[]>`, literally "_an observable of hero arrays_". In practice, it will only return a single hero array.

Expand Down Expand Up @@ -513,8 +513,8 @@ The `searchTerms` becomes an `Observable` emitting a steady stream of search ter
Passing a new search term directly to the `searchHeroes()` after every user keystroke would create an excessive amount of HTTP requests,
taxing server resources and burning through the cellular network data plan.

Instead, the `ngOnInit()` method pipes the `searchTerms` _observable_ through a sequence of RxJS operators that reduce the number of calls to the `searchHeroes()`,
ultimately returning an _observable_ of timely hero search results (each a `Hero[]`).
Instead, the `ngOnInit()` method pipes the `searchTerms` observable through a sequence of RxJS operators that reduce the number of calls to the `searchHeroes()`,
ultimately returning an observable of timely hero search results (each a `Hero[]`).

Here's the code.

Expand All @@ -529,7 +529,7 @@ Here's the code.
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.
* `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`.
Expand Down Expand Up @@ -648,7 +648,7 @@ You're at the end of your journey, and you've accomplished a lot.
* 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 Observables.
* You learned how to use observables.

This concludes the "Tour of Heroes" tutorial.
You're ready to learn more about Angular development in the fundamentals section,
Expand Down