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

Commit 5001355

Browse files
Added section on operators
1 parent 97d73cc commit 5001355

File tree

5 files changed

+165
-1
lines changed

5 files changed

+165
-1
lines changed

public/docs/_examples/rxjs/ts/app/hero-counter.component.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// #docplaster
22
// #docregion
3+
import 'rxjs/add/operator/takeUntil';
34
import { Component, OnInit, OnDestroy } from '@angular/core';
45
import { Subject } from 'rxjs/Subject';
56
import { Observable } from 'rxjs/Observable';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// #docplaster
2+
// #docregion
3+
// #docregion operator-import
4+
import 'rxjs/add/operator/do';
5+
import 'rxjs/add/operator/filter';
6+
// #docregion operator
7+
import { Component, OnInit } from '@angular/core';
8+
9+
import { HeroService } from './hero.service';
10+
import { Hero } from './hero';
11+
12+
@Component({
13+
template: `
14+
<h2>HEROES</h2>
15+
<ul class="items">
16+
<li *ngFor="let hero of heroes">
17+
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
18+
</li>
19+
</ul>
20+
`
21+
})
22+
export class HeroListComponent implements OnInit {
23+
heroes: Hero[];
24+
25+
constructor(
26+
private service: HeroService
27+
) {}
28+
29+
ngOnInit() {
30+
this.service.getHeroes()
31+
.do(heroes => {
32+
console.log(heroes.length);
33+
})
34+
.filter(heroes => heroes.length > 2)
35+
.subscribe(heroes => this.heroes = heroes);
36+
}
37+
}
38+
// #enddocregion operator-import
39+
40+
// #docregion import-all
41+
import 'rxjs/Rx';
42+
// #enddocregion import-all
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// #docplaster
2+
// #docregion
3+
import { _do } from 'rxjs/operator/do';
4+
import { filter } from 'rxjs/operator/filter';
5+
import { Component, OnInit } from '@angular/core';
6+
7+
import { HeroService } from './hero.service';
8+
import { Hero } from './hero';
9+
10+
@Component({
11+
template: `
12+
<h2>HEROES</h2>
13+
<ul class="items">
14+
<li *ngFor="let hero of heroes">
15+
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
16+
</li>
17+
</ul>
18+
`
19+
})
20+
export class HeroListComponent implements OnInit {
21+
heroes: Hero[];
22+
23+
constructor(
24+
private service: HeroService
25+
) {}
26+
27+
ngOnInit() {
28+
const heroes$ = this.service.getHeroes();
29+
const loggedHeroes$ = _do.call(heroes$, heroes => {
30+
console.log(heroes.length);
31+
});
32+
const filteredHeroes$ = filter.call(loggedHeroes$, heroes => heroes.length > 2);
33+
34+
filteredHeroes$.subscribe(heroes => this.heroes = heroes);
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// #docplaster
2+
// #docregion
3+
// #docregion filter-import
4+
import 'rxjs/add/operator/filter';
5+
// #enddocregion filter-import
6+
// #docregion operator
7+
import { Component, OnInit } from '@angular/core';
8+
9+
import { HeroService } from './hero.service';
10+
import { Hero } from './hero';
11+
12+
@Component({
13+
template: `
14+
<h2>HEROES</h2>
15+
<ul class="items">
16+
<li *ngFor="let hero of heroes">
17+
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
18+
</li>
19+
</ul>
20+
`
21+
})
22+
export class HeroListComponent implements OnInit {
23+
heroes: Hero[];
24+
25+
constructor(
26+
private service: HeroService
27+
) {}
28+
29+
ngOnInit() {
30+
this.service.getHeroes()
31+
.filter(heroes => heroes.length > 2)
32+
.subscribe(heroes => this.heroes = heroes);
33+
}
34+
}
35+
// #enddocregion

public/docs/ts/latest/guide/rxjs.jade

+51-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ block includes
1616
## Table of Contents
1717
* [The Observable](#definition "")
1818
* [Observables and Promises](#observables-vs-promises "")
19+
* [Operators](#operators "")
1920
* [Framework APIs](#apis "")
2021
* [Error Handling](#error-handling "")
2122
* [Further Reading](#reading "")
@@ -61,10 +62,59 @@ h3#observables-vs-promises Observables and Promises: More different than alike
6162
tool to handle the various streams of events in an application. So does this mean Promises are no longer needed? Absolutely not. Promises will continue to serve a purpose as
6263
the right tool for the job in some situations.
6364

65+
h3#operators Operators: Import them and use them
66+
67+
:marked
68+
Operators are pure functions that extend the Observable interface, allow you to perform an action against the Observable
69+
and return a new Observable. An Observable comes with very few built-in operators and the rest of the operators are
70+
added to the Observable on demand. There are multiple approaches to make these operators available for use.
71+
One approach is to import the entire RxJS library.
72+
73+
+makeExcerpt('app/heroes-filtered.component.1.ts', 'import-all')
74+
75+
:marked
76+
This is the **least recommended** method, as it brings in **all** the Observables operators,
77+
even ones you never use. While convenient, this method is inefficient and can greatly impact the size of your application,
78+
which is always a concern. This method is mainly reserved for prototyping and testing, where such concerns are less important.
79+
80+
The second method is to import operators selectively by patching the Observable prototype. This allows you to chain
81+
operators together, as each operator returns a new Observable. Below is an example of importing the `filter` and `do` operators.
82+
The `filter` operator filters elements produced by an Observable based on a predicate function that returns a boolean. The `do` operator
83+
provides the Observable value to perform an arbitrary action, such as console logging.
84+
85+
+makeExcerpt('app/heroes-filtered.component.1.ts', 'operator-import')
86+
87+
:marked
88+
Had you not imported these common operators before using them with the Observable returned by `getHeroes`,
89+
the Observable would fail to perform these actions as it these functions don't exist on the Observable yet.
90+
91+
Another common example is two components with incomplete operator imports. Both files have components that use Observable operators
92+
but only one file imports the operators it needs. Interestingly enough if you load the component with the imported operators first and then
93+
load the second component, everything works fine. Conversely, loading the component without the imported operators first blows up because the
94+
operators aren't available on the Observable.
95+
96+
Another approach is to import the Observable operators directly and call them individually on the Observable. Let's
97+
update your filtered heroes component to use direct imports.
98+
99+
+makeExcerpt('app/heroes-filtered.component.2.ts (direct operator imports)', '')
100+
101+
:marked
102+
This approach has no side-effects as you're not patching the Observable prototype. It also is
103+
more conducive to tree shaking versus patching the Observable prototype, which can't be tree-shaken. You're also only importing what you need where you need it,
104+
but this approach doesn't give you the option to chain operators together. If you were building a third-party
105+
library, this would be the recommended approach as you don't want your library to produce any side-effects
106+
to the Observable for consumers of your library but for an application, its less desirable.
107+
108+
The recommended approach is to import the operators in the file where you use them. Yes, this may lead to
109+
duplicate imports of operators in multiple files, but more importantly this ensures that the operators
110+
that are needed are provided by that file. This becomes especially important with lazy loading, where
111+
certain feature areas may only make use of certain operators. Importing the operators this way ensures
112+
the operators are available regardless of where and when you use them.
113+
64114
h3#managing-subscriptions Managing Subscriptions
65115

66116
:marked
67-
Observables like any other instance use resources and those resources add to the overall resources used in your application. Observables
117+
Observables like any other instance use resources and those resources add to the overall weight of your application over time. Observables
68118
provide a `Subscription` for each `Subscriber` of the Observable that comes with a way to _unsubscribe_ or clean up any resources used
69119
while listening for values produced by the Observable. We'll look at a simple example of how to unsubscribe from and Observable once
70120
its no longer needed.

0 commit comments

Comments
 (0)