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

Commit f71f979

Browse files
docs(rxjs): Added developer guide on Observables
1 parent 35bbeb2 commit f71f979

30 files changed

+944
-0
lines changed

Diff for: public/docs/_examples/rxjs/e2e-spec.ts

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict'; // necessary for es6 output in node
2+
3+
import { browser
4+
/*, element, by, ElementFinder*/
5+
} from 'protractor';
6+
7+
describe('RxJS', function () {
8+
9+
beforeAll(function () {
10+
browser.get('');
11+
});
12+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Injectable } from '@angular/core';
2+
import { Response } from '@angular/http';
3+
import { Observable } from 'rxjs/Observable';
4+
5+
export interface ApiError {
6+
message: string;
7+
}
8+
9+
@Injectable()
10+
export class ApiErrorHandlerService {
11+
handle(resp: Response): Observable<Error> {
12+
return Observable.of(resp)
13+
.switchMap(response => {
14+
15+
let error: ApiError;
16+
17+
try {
18+
error = response.json().error;
19+
} catch (e) {
20+
if (response.status === 404) {
21+
error = {
22+
message: 'The requested resource was not found'
23+
};
24+
} else {
25+
error = {
26+
message: 'An unknown error has occurred'
27+
};
28+
}
29+
}
30+
31+
return Observable.throw(error);
32+
});
33+
}
34+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// #docplaster
2+
// #docregion
3+
import { NgModule } from '@angular/core';
4+
import { RouterModule, Routes } from '@angular/router';
5+
import { HomeComponent } from './home.component';
6+
import { HeroDetailComponent } from './hero-detail.component';
7+
import { HeroSearchComponent } from './hero-search.component';
8+
9+
const appRoutes: Routes = [
10+
{ path: '', component: HomeComponent },
11+
{ path: 'hero/search', component: HeroSearchComponent },
12+
{ path: 'hero/:id', component: HeroDetailComponent }
13+
];
14+
15+
@NgModule({
16+
imports: [RouterModule.forRoot(appRoutes)],
17+
exports: [RouterModule]
18+
})
19+
export class AppRoutingModule {}

Diff for: public/docs/_examples/rxjs/ts/app/app.component.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// #docplaster
2+
// #docregion
3+
import { Component } from '@angular/core';
4+
5+
@Component({
6+
selector: 'my-app',
7+
template: `
8+
<h1 class="title">RxJS in Angular</h1>
9+
10+
<router-outlet></router-outlet>
11+
<loading-component></loading-component>
12+
`
13+
})
14+
export class AppComponent {
15+
}

Diff for: public/docs/_examples/rxjs/ts/app/app.module.ts

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// #docregion
2+
import { NgModule } from '@angular/core';
3+
import { BrowserModule } from '@angular/platform-browser';
4+
import { HttpModule } from '@angular/http';
5+
import { ReactiveFormsModule } from '@angular/forms';
6+
7+
import { AppComponent } from './app.component';
8+
import { AppRoutingModule } from './app-routing.module';
9+
import { HomeComponent } from './home.component';
10+
import { HeroesReadyComponent } from './heroes-ready.component';
11+
import { CounterComponent } from './counter.component';
12+
import { FormFieldComponent } from './form-field.component';
13+
import { LoadingComponent } from './loading.component';
14+
import { HeroSearchComponent } from './hero-search.component';
15+
import { HeroDetailComponent } from './hero-detail.component';
16+
import { HeroListComponent } from './hero-list.component';
17+
18+
import { LoadingService } from './loading.service';
19+
import { HeroService } from './hero.service';
20+
21+
// Imports for loading & configuring the in-memory web api
22+
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
23+
import { InMemoryDataService } from './in-memory-data.service';
24+
import { ApiErrorHandlerService } from './api-error-handler.service';
25+
26+
@NgModule({
27+
imports: [
28+
BrowserModule,
29+
HttpModule,
30+
AppRoutingModule,
31+
ReactiveFormsModule,
32+
InMemoryWebApiModule.forRoot(InMemoryDataService)
33+
],
34+
declarations: [
35+
AppComponent,
36+
HomeComponent,
37+
HeroesReadyComponent,
38+
CounterComponent,
39+
FormFieldComponent,
40+
LoadingComponent,
41+
HeroSearchComponent,
42+
HeroDetailComponent,
43+
HeroListComponent
44+
],
45+
providers: [
46+
HeroService,
47+
LoadingService,
48+
ApiErrorHandlerService
49+
],
50+
bootstrap: [ AppComponent ]
51+
})
52+
export class AppModule {
53+
}
54+
// #enddocregion
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// #docplaster
2+
// #docregion
3+
import { Component, OnInit, OnDestroy } from '@angular/core';
4+
import { Subject } from 'rxjs/Subject';
5+
import { Subscription } from 'rxjs/Subscription';
6+
7+
@Component({
8+
selector: 'counter-component',
9+
template: `
10+
<p>
11+
Hero Counter: {{ count }}
12+
13+
<button (click)="increment()">Increment</button>
14+
</p>
15+
`
16+
})
17+
export class CounterComponent implements OnInit, OnDestroy {
18+
count: number = 0;
19+
counter$ = new Subject();
20+
sub: Subscription;
21+
22+
ngOnInit() {
23+
this.sub = this.counter$.subscribe();
24+
}
25+
26+
increment() {
27+
this.counter$.next(this.count++);
28+
}
29+
30+
ngOnDestroy() {
31+
this.sub.unsubscribe();
32+
}
33+
}
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// #docplaster
2+
// #docregion
3+
import 'rxjs/add/operator/takeUntil';
4+
import { Component, OnInit, OnDestroy } from '@angular/core';
5+
import { Subject } from 'rxjs/Subject';
6+
7+
@Component({
8+
selector: 'counter-component',
9+
template: `
10+
<p>
11+
Counter: {{ count }}
12+
13+
<button (click)="increment()">Increment</button>
14+
</p>
15+
`
16+
})
17+
export class CounterComponent implements OnInit, OnDestroy {
18+
count: number = 0;
19+
counter$ = new Subject();
20+
destroy$: Subject<any> = new Subject();
21+
22+
ngOnInit() {
23+
this.counter$.takeUntil(this.destroy$).subscribe();
24+
}
25+
26+
increment() {
27+
this.counter$.next(this.count++);
28+
}
29+
30+
ngOnDestroy() {
31+
this.destroy$.next();
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Injectable } from '@angular/core';
2+
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
3+
4+
export interface Event {
5+
type: string;
6+
message: string;
7+
}
8+
9+
@Injectable()
10+
export class EventAggregatorService {
11+
_events: Event[];
12+
events$: BehaviorSubject<Event[]> = new BehaviorSubject<any>([]);
13+
14+
add(event: Event) {
15+
this._events.push(event);
16+
this.next();
17+
}
18+
19+
clear() {
20+
this._events = [];
21+
this.next();
22+
}
23+
24+
next() {
25+
this.events$.next(this._events);
26+
}
27+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// #docplaster
2+
// #docregion
3+
import 'rxjs/add/observable/of';
4+
import 'rxjs/add/observable/fromEvent';
5+
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
6+
import { Observable } from 'rxjs/Observable';
7+
8+
@Component({
9+
selector: 'form-field-component',
10+
template: `
11+
<h3>Observable Form Field</h3>
12+
<p>
13+
<input type="text" #name>
14+
<span *ngIf="blurred$ | async">Blurred</span>
15+
</p>
16+
`
17+
})
18+
export class FormFieldComponent implements OnInit {
19+
@ViewChild('name', { read: ElementRef }) name: ElementRef;
20+
21+
blurred$: Observable<boolean>;
22+
23+
ngOnInit() {
24+
this.blurred$ = Observable.fromEvent(this.name.nativeElement, 'blur');
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// #docplaster
2+
// #docregion
3+
import 'rxjs/add/observable/of';
4+
import 'rxjs/add/operator/map';
5+
import 'rxjs/add/operator/do';
6+
import 'rxjs/add/operator/filter';
7+
import { Component, OnInit } from '@angular/core';
8+
import { ActivatedRoute, Params } from '@angular/router';
9+
import { HeroService } from './hero.service';
10+
import { Hero } from './hero';
11+
import { Observable } from 'rxjs/Observable';
12+
13+
@Component({
14+
template: `
15+
<div *ngIf="loading">
16+
Loading Hero...
17+
</div>
18+
<div *ngIf="hero">
19+
<h3>HEROES</h3>
20+
<div>
21+
<label>Id: </label>{{ hero.id }}
22+
</div>
23+
<div>
24+
<label>Name: </label>
25+
<input placeholder="name" [value]="hero.name"/>
26+
</div>
27+
</div>
28+
<div *ngIf="error">
29+
No hero found
30+
</div>
31+
`
32+
})
33+
export class HeroDetailComponent implements OnInit {
34+
hero: Hero;
35+
loading: boolean = true;
36+
error: boolean;
37+
38+
constructor(
39+
private heroService: HeroService,
40+
private route: ActivatedRoute
41+
) {}
42+
43+
ngOnInit() {
44+
this.route.params
45+
.do(() => this.loading = true)
46+
.switchMap((params: Params) =>
47+
this.heroService.getHero(params['id'])
48+
.catch(error => {
49+
this.error = true;
50+
51+
return Observable.of(null);
52+
})
53+
)
54+
.do(() => this.loading = false)
55+
.subscribe((hero: Hero) => this.hero = hero);
56+
}
57+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// #docplaster
2+
// #docregion
3+
import { Component, OnInit } from '@angular/core';
4+
5+
import { HeroService } from './hero.service';
6+
import { Hero } from './hero';
7+
8+
@Component({
9+
selector: 'hero-list',
10+
template: `
11+
<h2>HEROES</h2>
12+
<ul class="items">
13+
<li *ngFor="let hero of heroes">
14+
<span class="badge">{{ hero.id }}</span> {{ hero.name }}
15+
</li>
16+
</ul>
17+
`
18+
})
19+
export class HeroListComponent implements OnInit {
20+
heroes: Hero[];
21+
22+
constructor(
23+
private service: HeroService
24+
) {}
25+
26+
ngOnInit() {
27+
this.service.getHeroes()
28+
.subscribe(heroes => this.heroes = heroes);
29+
}
30+
}
31+
// #enddocregion
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// #docplaster
2+
// #docregion
3+
import 'rxjs/add/operator/toPromise';
4+
import { Component, OnInit } from '@angular/core';
5+
6+
import { HeroService } from './hero.service';
7+
import { Hero } from './hero';
8+
9+
@Component({
10+
selector: 'hero-list',
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+
this.service.getHeroes()
29+
.toPromise()
30+
.then((heroes: Hero[]) => this.heroes = heroes);
31+
}
32+
}
33+
// #enddocregion

0 commit comments

Comments
 (0)