Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added aio/content/examples/.DS_Store
Binary file not shown.
4 changes: 4 additions & 0 deletions aio/content/examples/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,7 @@ aot-compiler/**/*.factory.d.ts
# ngUpgrade testing
!upgrade-phonecat-*/**/karma.conf.js
!upgrade-phonecat-*/**/karma-test-shim.js

# rxjs
!rxjs/src/browser-test-shim.js
!rxjs/src/jasmine-marbles.umd.js
62 changes: 62 additions & 0 deletions aio/content/examples/rxjs/e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use strict'; // necessary for es6 output in node

import { browser, element, by, ElementFinder, ElementArrayFinder } from 'protractor';

describe('RxJS', function () {
let page: any;

function getPage() {
return {
findHrefs: () => element.all(by.css('my-app a')),
findHeroes: () => element(by.linkText('Heroes')),
findHeroCounter: () => element(by.linkText('Hero Counter')),

findMessageLog: () => element(by.css('message-log')),
findHeroList: () => element(by.css('ul.items')),
findHeroListItems: () => element.all(by.css('ul.items li')),

findHeroDetailDivs: () => element.all(by.css('ng-component div div'))
};
}

beforeAll(function () {
browser.get('');
});

beforeEach(() => {
page = getPage();
});

it('should have 10 heroes', async() => {
const heroes: ElementArrayFinder = page.findHeroListItems();

expect(await heroes.count()).toBe(10);
});

it('should have 1 initial event log items', async() => {
const log: ElementFinder = page.findMessageLog();
const logItems: ElementArrayFinder = log.all(by.css('ul li'));

expect(await logItems.count()).toBe(1);
});

xit('should add log entries after leaving hero counter page', async() => {
const heroCounter: ElementFinder = page.findHeroCounter();
const heroes: ElementFinder = page.findHeroes();
const log: ElementFinder = page.findMessageLog();
const logItems: ElementArrayFinder = log.all(by.css('ul li'));
await heroCounter.click();
await heroes.click();

expect(await logItems.count()).toBe(9);
});

it('should display hero details', async () => {
const hero: ElementFinder = page.findHeroListItems().first().element(by.css('a'));
const heroDetailDivs = page.findHeroDetailDivs();
await hero.click();

expect(await heroDetailDivs.first().getText()).toContain('ID: 1');
expect(await heroDetailDivs.last().getText()).toContain('Name: Mr. Nice');
});
});
Empty file.
10 changes: 10 additions & 0 deletions aio/content/examples/rxjs/plnkr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"description": "RxJS",
"basePath": "src/",
"files":[
"!**/*.d.ts",
"!**/*.js",
"!**/*.[0-9].*"
],
"tags": ["rxjs", "observable"]
}
18 changes: 18 additions & 0 deletions aio/content/examples/rxjs/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { HeroListComponent } from './hero-list.component';
import { HeroCounterComponent } from './hero-counter.component';
import { HeroDetailComponent } from './hero-detail.component';

const appRoutes: Routes = [
{ path: 'hero/counter', component: HeroCounterComponent },
{ path: 'hero/:id', component: HeroDetailComponent },
{ path: 'heroes', component: HeroListComponent },
{ path: '', redirectTo: '/heroes', pathMatch: 'full' },
];

@NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [RouterModule]
})
export class AppRoutingModule {}
36 changes: 36 additions & 0 deletions aio/content/examples/rxjs/src/app/app.component.1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
import { EventAggregatorService } from './event-aggregator.service';
import { ObservablePrinciples } from './observable-principles';

// #docregion message-log
@Component({
selector: 'my-app',
template: `
<h1 class="title">RxJS in Angular</h1>

<a routerLink="/heroes">Heroes</a><br>
<a routerLink="/hero/counter">Hero Counter</a><br>

<router-outlet></router-outlet>

<message-log></message-log>
`
})
// #enddocregion message-log
export class AppComponent implements OnInit {
constructor(
private eventService: EventAggregatorService,
private principles: ObservablePrinciples) {}

ngOnInit() {
this.eventService.add({
type: 'init',
message: 'Application Initialized'
});

this.principles.callFunctionalExamples();
this.principles.callPromiseExamples();
}
}
29 changes: 29 additions & 0 deletions aio/content/examples/rxjs/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// #docplaster
// #docregion
import { Component, OnInit } from '@angular/core';
import { EventAggregatorService } from './event-aggregator.service';

@Component({
selector: 'my-app',
template: `
<h1 class="title">RxJS in Angular</h1>

<a routerLink="/heroes">Heroes</a><br>
<a routerLink="/hero/counter">Hero Counter</a><br>

<router-outlet></router-outlet>

<message-log></message-log>
`
})
export class AppComponent implements OnInit {
constructor(
private eventService: EventAggregatorService) {}

ngOnInit() {
this.eventService.add({
type: 'init',
message: 'Application Initialized'
});
}
}
47 changes: 47 additions & 0 deletions aio/content/examples/rxjs/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// #docregion
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpModule } from '@angular/http';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HeroListComponent } from './hero-list.component';
import { HeroCounterComponent } from './hero-counter.component';
import { MessageLogComponent } from './message-log.component';
import { HeroDetailComponent } from './hero-detail.component';

import { HeroService } from './hero.service';

// #docregion event-aggregator-import
import { EventAggregatorService } from './event-aggregator.service';
// #enddocregion event-aggregator-import

// Imports for loading & configuring the in-memory web api
import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService } from './in-memory-data.service';

@NgModule({
imports: [
BrowserModule,
HttpModule,
AppRoutingModule,
ReactiveFormsModule,
InMemoryWebApiModule.forRoot(InMemoryDataService)
],
declarations: [
AppComponent,
HeroCounterComponent,
HeroListComponent,
MessageLogComponent,
HeroDetailComponent
],
providers: [
HeroService,
EventAggregatorService
],
bootstrap: [ AppComponent ]
})
export class AppModule {
}
// #enddocregion
44 changes: 44 additions & 0 deletions aio/content/examples/rxjs/src/app/event-aggregator.service.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// #docregion
// #docplaster
// #docregion testing-1
import { TestBed } from '@angular/core/testing';
import { EventAggregatorService, AppEvent } from './event-aggregator.service';

describe('Event Aggregator Service', () => {
let eventService: EventAggregatorService;

beforeEach(() => {
TestBed.configureTestingModule({
providers: [
EventAggregatorService
]
});

eventService = TestBed.get(EventAggregatorService);
});
// #enddocregion testing-1
// #docregion testing-2
it('should start with an empty array', () => {
eventService.events$.subscribe(events => {
expect(events.length).toBe(0);
});
});
// #enddocregion testing-2
// #docregion testing-3
it('should append new events to the array when add() is called', () => {
const event: AppEvent = {
type: 'Event',
message: 'An event occurred'
};

eventService.add(event);

eventService.events$.subscribe(events => {
expect(events.length).toBe(1);
expect(events[0]).toEqual(event);
});
});
// #enddocregion testing-3
// #docregion testing-1
});
// #enddocregion testing-1
25 changes: 25 additions & 0 deletions aio/content/examples/rxjs/src/app/event-aggregator.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// #docplaster
// #docregion
// #docregion imports
import 'rxjs/add/operator/scan';
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
// #enddocregion imports

// #docregion event-interface
export interface AppEvent {
type: string;
message: string;
}
// #enddocregion event-interface

@Injectable()
export class EventAggregatorService {
_events$: BehaviorSubject<AppEvent[]> = new BehaviorSubject<AppEvent[]>([]);
events$ = this._events$
.scan((events, event) => events.concat(event), []);

add(event: AppEvent) {
this._events$.next([event]);
}
}
40 changes: 40 additions & 0 deletions aio/content/examples/rxjs/src/app/hero-counter.component.1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// #docplaster
// #docregion
// #docregion counter-unsubscribe
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { Subscription } from 'rxjs/Subscription';

@Component({
selector: 'hero-counter',
template: `
<h2>HERO COUNTER</h2>
<p>
Heroes {{ count }}
</p>
`
})
export class HeroCounterComponent implements OnInit, OnDestroy {
count = 0;
counter$: Observable<number>;
sub: Subscription;

ngOnInit() {
this.counter$ = Observable.create((observer: Observer<number>) => {
setInterval(() => {
observer.next(this.count++);
}, 1000);
});

this.sub = this.counter$.subscribe();
}
// #enddocregion counter-unsubscribe
// #docregion ngOnDestroy-unsubscribe
ngOnDestroy() {
this.sub.unsubscribe();
}
// #enddocregion ngOnDestroy-unsubscribe
// #docregion counter-unsubscribe
}
// #enddocregion
57 changes: 57 additions & 0 deletions aio/content/examples/rxjs/src/app/hero-counter.component.2.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// #docplaster
// #docregion
// #docregion takeUntil-operator
import 'rxjs/add/operator/takeUntil';
// #enddocregion takeUntil-operator
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';

// #docregion import-subject
import { Subject } from 'rxjs/Subject';
// #enddocregion import-subject

@Component({
selector: 'hero-counter',
template: `
<h2>HERO COUNTER</h2>
<p>
Heroes {{ count }}
</p>
`
})
export class HeroCounterComponent implements OnInit, OnDestroy {
count = 0;
counter$: Observable<number>;

// #docregion onDestroy-subject
onDestroy$ = new Subject();
// #enddocregion onDestroy-subject

ngOnInit() {
this.counter$ = Observable.create((observer: Observer<number>) => {
setInterval(() => {
observer.next(this.count++);
}, 1000);
});

this.counter$
.takeUntil(this.onDestroy$)
.subscribe();

this.counter$
.takeUntil(this.onDestroy$)
.subscribe();

this.counter$
.takeUntil(this.onDestroy$)
.subscribe();
}

// #docregion ngOnDestroy-complete
ngOnDestroy() {
this.onDestroy$.complete();
}
// #enddocregion ngOnDestroy-complete
}
// #enddocregion
Loading