SlideShare a Scribd company logo
Reactive programming in
Angular 2
Yakov Fain
yfain
About myself
• Solutions Architect at Farata Systems
• Java Champion
• Co-authored the book

“Angular Development with TypeScript”
The Agenda
• Intro to RxJS



- Observable

- Observer

- Operators
• Observables in Angular 2



- Forms

- Http

- Router
RxJS 5
• Github repo:

https://github.com/ReactiveX/rxjs
• CDN: 

https://unpkg.com/@reactivex/rxjs/dist/global/Rx.js
• Installing RxJS in the npm-based projects:



npm install rxjs
• Documentation:

http://reactivex.io/rxjs 

Main RxJS players
• Observable - a producer of sequences of values
• Observer - a consumer of observable values
• Subscriber - connects observer with observable
• Operator - en-route value transformation
Data

Source 

Data Flow
Observable
 Data

Source 

Data Flow
Observable
 Data

Source 

Data Flow
next
Observable
SubscriberObserver Data

Source 

Data Flow
next
Observable
SubscriberObserver Data

Source 

Data Flow
next
next()
error()
complete()
An Observable allows:
• Subscribe/unsubscribe to its data stream
• Emit the next value to the observer
• Notify the observer about errors
• Inform the observer about the stream completion
An Observer provides:
• A function to handle the next value from the stream
• A function to handle errors
• A function to handle end-of-stream
Creating an Observable
• Observable.create() - returns Observable that can invoke methods on Observer
• Observable.from() - converts an array or iterable into Observable
• Observable.fromEvent() - converts an event into Observable
• Observable.fromPromise() - converts a Promise into Observable
• Observable.range() - returns a sequence of integers in the specified range
An Operator
Observable Observable
A transforming

function
Let’s have a beer
let beers = [

{name: "Stella", country: "Belgium", price: 9.50},

{name: "Sam Adams", country: "USA", price: 8.50},

{name: "Bud Light", country: "USA", price: 6.50},

{name: "Brooklyn Lager", country: "USA", price: 8.00},

{name: "Sapporo", country: "Japan", price: 7.50}

];

An Operator
Observable Observable
A transforming

function
observableBeers

.filter(beer => beer.price < 8))
observableBeers = Rx.Observable.from(beers)

.filter(beer => beer.price < 8)

.map(beer => beer.name + ": $" + beer.price);



observableBeers

.subscribe(

beer => console.log(beer),

err => console.error(err),

() => console.log("Streaming is over")

);
Observable Beer
Creating the 

Observable
observableBeers = Rx.Observable.from(beers)

.filter(beer => beer.price < 8)

.map(beer => beer.name + ": $" + beer.price);



observableBeers

.subscribe(

beer => console.log(beer),

err => console.error(err),

() => console.log("Stream is over")

);
Operators
Observer
Observable Beer
observableBeers = Rx.Observable.from(beers)

.filter(beer => beer.price < 8)

.map(beer => beer.name + ": $" + beer.price);



observableBeers

.subscribe(

beer => console.log(beer),

err => console.error(err),

() => console.log("Streaming is over")

);
Observable Beer
No 

streaming yet
Streaming

begins
Demo
http://bit.ly/2kogm42


http://bit.ly/2jm69aM
Marble Diagrams
Observable map(function){}
Observable filter(function){}
RX: the data moves across your algorithm
Observable
Operator
Observable
Operator
Observable
Operator
Observable
Operator
Error-handling operators
• error() is invoked by the Observable on the Observer.
• catch() - intercepts the error in the subscriber before the observer gets it. You can
handle the error and re-subscribe.

• retry(n) - retry immediately up to n times

• retryWhen(fn) - retries as prescribed by the argument

// Declaring
function getData(): Observable {…} // data source 1

function getCachedData(): Observable {…} // data source 2
function getDataFromAnotherService(): Observable {…} // data source 3
//Invoking and subscribing
getData()

.catch(err => { 



if (err.status === 500){

console.error("Switching to streaming cached beer data");

return getCachedData();

} else{

console.error("Switching to another beer service");

return getDataFromAnotherService();

}



})

.map(beer => beer.name + ", " + beer.country)

.subscribe(

beer => console.log("Subscriber got " + beer)

);
F
a
i

l

o
v
e

r
Failover with catch()
plunker: http://bit.ly/2jXY9ha
flatMap
function getDrinks() {



let beers = Rx.Observable.from([

{name: "Stella", country: "Belgium", price: 9.50},

{name: "Sam Adams", country: "USA", price: 8.50},

{name: "Bud Light", country: "USA", price: 6.50}

]);



let softDrinks = Rx.Observable.from([

{name: "Coca Cola", country: "USA", price: 1.50},

{name: "Fanta", country: "USA", price: 1.50},

{name: "Lemonade", country: "France", price: 2.50}

]);



return Rx.Observable.create( observer => {



observer.next(beers); // pushing the beer pallet (observable)

observer.next(softDrinks); // pushing the soft drinks pallet (observable)

}

);

}



getDrinks()

.flatMap(drinks => drinks) // unloading drinks from pallets

.subscribe(

drink => console.log("Subscriber got " + drink.name + ": " + drink.price )
);
plunker http://bit.ly/2jZgc6T
Operator flatMap• Handles every value emitted by an observable as another observable
• Auto-subscribes to the internal observable and unwraps it
concat
Operator concat
Subscribe to the next observable only when the previous completes. It’s
useful for a sequential processing, e.g. HTTP requests.
// Emulate HTTP requests
let fourSecHTTPRequest = Rx.Observable.timer(4000).mapTo('First response');
let oneSecHTTPRequest = Rx.Observable.timer(1000).mapTo('Second response');
Rx.Observable
.concat(fourSecHTTPRequest, oneSecHTTPRequest)
.subscribe(res => console.log(res));
plunker http://bit.ly/2keEoiI
RxJS operators
http://reactivex.io/rxjs/manual/overview.html#categories-of-operators
Observables in
Angular
Code samples: https://github.com/yfain/observables
Observables in Forms
An input field: FormControl
• valueChanges - the value of the form control changes



this.searchInput.valueChanges.subscribe(…);
• statusChanges - status of the form control (valid/invalid)



this.password.statusChanges.subscribe(…);
Observable Events in Angular forms
@Component({

selector: "app",

template: `

<h2>Observable events demo</h2>

<input type="text" placeholder="Enter stock" [formControl]="searchInput">

`

})

class AppComponent {



searchInput: FormControl;



constructor(){

this.searchInput = new FormControl('');



this.searchInput.valueChanges

.debounceTime(500)

.subscribe(stock => this.getStockQuoteFromServer(stock));

}



getStockQuoteFromServer(stock) {



console.log(`The price of ${stock} is ${100*Math.random().toFixed(4)}`);

}

}
Observable
Demo 

main-formcontrol
Http and Observables


class AppComponent {



products: Array<string> = [];



constructor(private http: Http) {



this.http.get(‘/products')

.map(res => res.json())

.subscribe(

data => {



this.products=data;

},



err =>

console.log("Can't get products. Error code: %s, URL: %s ",

err.status, err.url),



() => console.log('Product(s) are retrieved')

);

}

}
O
b
s
e
r
v
e
r
@Component({

selector: 'http-client',

template: `<h1>All Products</h1>

<ul>

<li *ngFor="let product of products | async">

{{product.title}}

</li>

</ul>

<h2>{{errorMessage}}</h2>

`})

class AppComponent {



products: Observable<Array<string>>;

errorMessage: string;



constructor(private http: Http) {



this.products = this.http.get('/products')

.map(res => res.json())

.catch( err => {

this.errorMessage =`Can't get product details from ${err.url},

error ${err.status} `;

return Observable.empty();

});

}

}
async pipe
The switchMap operator
RxJS 5, official doc:

http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-
switchMap

Returns an Observable that emits items based on
applying a function that you supply to each item emitted
by the source Observable, where that function returns
an (so-called "inner") Observable. Each time it observes
one of these inner Observables, the output Observable
begins emitting the items emitted by that inner
Observable. When a new inner Observable is emitted,
switchMap stops emitting items from the earlier-emitted
inner Observable and begins emitting items from the
new one. It continues to behave like this for subsequent
inner Observables.
The switchMap operator
RxJS 5, official doc:

http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-
switchMap

Returns an Observable that emits items based on
applying a function that you supply to each item emitted
by the source Observable, where that function returns
an (so-called "inner") Observable. Each time it observes
one of these inner Observables, the output Observable
begins emitting the items emitted by that inner
Observable. When a new inner Observable is emitted,
switchMap stops emitting items from the earlier-emitted
inner Observable and begins emitting items from the
new one. It continues to behave like this for subsequent
inner Observables.
When a picture worth a thousand words
http://reactivex.io/documentation/operators/images/switchMap.png
The switchMap operator in English
• An outer observable emits the data and switches over to the inner
observable for processing
• If the outer observable emits the new data while the inner one is still
processing, the inner observable is terminated

• The inner observable starts processing the newly emitted data

• Example: A user types in a field (outer observable) and the HTTP
requests are being made (inner observable) as the user types
Killing HTTP requests with switchMap
<input type="text" placeholder="Enter city" [formControl]="searchInput">
…
this.searchInput.valueChanges

.debounceTime(200)

.switchMap(city => this.getWeather(city))

.subscribe(

res => {

this.temperature =

`Current temperature is ${res.main.temp}F, ` +

`humidity: ${res.main.humidity}%`;
},

err => console.log(`Can't get weather. Error code: %s, URL: %s`, err.message, err.url)

);

}



getWeather(city): Observable<Array> {

return this.http.get(this.baseWeatherURL + city + this.urlSuffix)

.map(res => res.json());

}
Outer Obs.
Inner Obs.
Demo 

main-http
Observables in the Router
Receiving params in ActivatedRoute
• Inject ActivatedRoute into a component to receive
route params during navigation
• Use ActivatedRoute.snapshot to get params once
• Use ActivatedRoute.param.subscribe() for
receiving multiple params over time
Subject: Observable + Observer
Can emit values and allows to subscribe to them
@Component({

selector: "app-root",

template: `

<h3>Using Subject for emitting/subscribing to keyup and input events</h3>

<input type="text" placeholder="Start typing" 

(input)="mySubject.next($event)" (keyup)="myKeySubject.next($event)">

`

})

export class AppComponent {



mySubject: Observable<Event> = new Subject(); // Observable for any events
myKeySubject: Observable<KeyboardEvent> = new Subject(); // Observable for keyboard events



constructor(){



this.myKeySubject.subscribe(({type, key}) => console.log(`Event: ${type} key: ${key}`));



this.mySubject.subscribe(({type, target}) => console.log(

`Event: ${type} value: ${(<HTMLInputElement>target).value}`));

}

}
Sharing an Observable
@Component({

selector: "app-root",

template: `

<h3>Sharing Observable between subscribers to keyup and input events</h3>

<input type="text" placeholder="Start typing" 

(input)="mySubject.next($event)" 

(keyup)="mySubject.next($event)">



<br> Subscriber to input events got {{inputValue}}

<p>

<br> Subscriber to input events got {{keyValue}} 

`

})

export class AppComponent {



keyValue: string;

inputValue: string;



mySubject: Observable<Event> = new Subject().share(); // Single Observable for any events



constructor(){



// Subscriber 1

this.mySubject

.filter(({type}) => type==="keyup")

.map(e => (<KeyboardEvent>e).key)

.subscribe((value) => this.keyValue=value);



// Subscriber 2

this.mySubject

.filter(({type}) => type==="input")

.map(e => (<HTMLInputElement>e.target).value)

.subscribe((value) => this.inputValue=value);

}

}
@Component({

selector: "app",

template: `

<h2>Sharing the same stream</h2>

<input #myinput type="text" placeholder="Start typing" >
<br> Subscribing to each value: {{data1}}

<br> Subscribing to 3-second samples: {{data2}}

`})

class AppComponent {


@ViewChild('myinput') myInputField: ElementRef;



data1: string;

data2: string;



ngAfterViewInit(){



let keyup$: Observable = Observable.fromEvent(this.myInputField.nativeElement, 'keyup');



let keyupValue$ = keyup$

.map(event => event.target.value)

.share();



// Subscribe to each keyup

keyupValue$

.subscribe(value => this.data1 = value);



// Subscribe to 3-second samples

keyupValue$

.sample(Observable.interval(3000))

.subscribe(value => this.data2 = value);

}

}
Accessing native elements with ElementRef
Using ElementRef

is not recommended
Demo
main-subject

main-subject-shared
Subscribing to EventEmitter
export declare class EventEmitter<T> extends Subject<T> {}
myEvent: EventEmitter<string> = new EventEmitter();
myEvent.emit("Hello World");
…
myEvent.subscribe(event => console.log(" Received " + event);
Your app:
Angular:
Has Observer

and Observable
Injectable service as Mediator
Subscribing to EventEmitter
export declare class EventEmitter<T> extends Subject<T> {}
myEvent: EventEmitter<string> = new EventEmitter();
myEvent.emit("Hello World");
…
myEvent.subscribe(event => console.log(" Received " + event);
Your app:
Angular:
Mediator, DI, Events, and Observables
StateService
Component1
with injected
StateService
Component2
with injected
StateService
EventEmitter
Emit event

on StateService
Subscribe to event

of StateService
Demo
main-mediator-service
WebSockets and Observables
Wrapping WebSocket into Observable
import {Observable } from 'rxjs/Observable';



export class BidService{



ws: WebSocket;



createObservableSocket(url:string): Observable{



this.ws = new WebSocket(url);



return new Observable(

observer => {



this.ws.onmessage = (event) => observer.next(event.data);



this.ws.onerror = (event) => observer.error(event);



this.ws.onclose = (event) => observer.complete();

});

}



}
Subscribing to WebSocket’s messages
@Component({ … })

class BidComponent {

newBid: Bid;



constructor(private wsService: BidService) {



this.wsService.createObservableSocket("ws://localhost:8085")

.map(res => JSON.parse(res))

.subscribe(

data => {



this.newBid = data;

this.newBid.bidTime= Date.parse(data.bidTime);

console.log(this.newBid);

},

err => console.log( err),

() => console.log( 'The bid stream is complete')

);

}



}
Demo1. Open http_websocket_samples

2. systemjs.config: bids/bid-component.ts
3. npm run tsc



4.npm run bidServer



5.http://localhost:8000
Summary
• Everything is an observable
• No data is pushed to you until you subscribe
• Chain the operators to pre-process the observable data before it gets
to the subscriber
• Angular offers you ready-to-use observables in multiple components
and services
• You can wrap the data pushed to your app into an Observable
Thank you!
• Code samples:

https://github.com/yfain/observables
• Training inquiries: 

training@faratasystems.com
• My blog:

yakovfain.com
• Twitter: @yfain


More Related Content

What's hot (20)

Practical RxJava for Android
Practical RxJava for Android
Tomáš Kypta
 
React state management with Redux and MobX
React state management with Redux and MobX
Darko Kukovec
 
Rx java in action
Rx java in action
Pratama Nur Wijaya
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
Fabio Collini
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
Frank Lyaruu
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to Rx
Andrzej Sitek
 
Bulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & Couchbase
Alex Derkach
 
Reactive programming with RxJava
Reactive programming with RxJava
Jobaer Chowdhury
 
Reactive Java (GeeCON 2014)
Reactive Java (GeeCON 2014)
Tomasz Kowalczewski
 
Reactive Java (33rd Degree)
Reactive Java (33rd Degree)
Tomasz Kowalczewski
 
Introduction to Reactive Java
Introduction to Reactive Java
Tomasz Kowalczewski
 
RxJava from the trenches
RxJava from the trenches
Peter Hendriks
 
Rxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJava
Kros Huang
 
Angular2 Development for Java developers
Angular2 Development for Java developers
Yakov Fain
 
Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular
Jalpesh Vadgama
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
Fabio Biondi
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8
Martin Toshev
 
Reactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - RxJava
Ali Muzaffar
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Frank Lyaruu
 
Reactive Android: RxJava and beyond
Reactive Android: RxJava and beyond
Fabio Tiriticco
 
Practical RxJava for Android
Practical RxJava for Android
Tomáš Kypta
 
React state management with Redux and MobX
React state management with Redux and MobX
Darko Kukovec
 
Introduction to Retrofit and RxJava
Introduction to Retrofit and RxJava
Fabio Collini
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
Frank Lyaruu
 
Streams, Streams Everywhere! An Introduction to Rx
Streams, Streams Everywhere! An Introduction to Rx
Andrzej Sitek
 
Bulding a reactive game engine with Spring 5 & Couchbase
Bulding a reactive game engine with Spring 5 & Couchbase
Alex Derkach
 
Reactive programming with RxJava
Reactive programming with RxJava
Jobaer Chowdhury
 
RxJava from the trenches
RxJava from the trenches
Peter Hendriks
 
Rxjava 介紹與 Android 中的 RxJava
Rxjava 介紹與 Android 中的 RxJava
Kros Huang
 
Angular2 Development for Java developers
Angular2 Development for Java developers
Yakov Fain
 
Top 10 RxJs Operators in Angular
Top 10 RxJs Operators in Angular
Jalpesh Vadgama
 
Angular & RXJS: examples and use cases
Angular & RXJS: examples and use cases
Fabio Biondi
 
Concurrency Utilities in Java 8
Concurrency Utilities in Java 8
Martin Toshev
 
Reactive Programming on Android - RxAndroid - RxJava
Reactive Programming on Android - RxAndroid - RxJava
Ali Muzaffar
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Frank Lyaruu
 
Reactive Android: RxJava and beyond
Reactive Android: RxJava and beyond
Fabio Tiriticco
 

Viewers also liked (20)

Angular 4 for Java Developers
Angular 4 for Java Developers
Yakov Fain
 
Angular 2 for Java Developers
Angular 2 for Java Developers
Yakov Fain
 
Angular 2 Essential Training
Angular 2 Essential Training
Patrick Schroeder
 
Building Universal Applications with Angular 2
Building Universal Applications with Angular 2
Minko Gechev
 
Integrating consumers IoT devices into Business Workflow
Integrating consumers IoT devices into Business Workflow
Yakov Fain
 
Data Flow Patterns in Angular 2 - Sebastian Müller
Data Flow Patterns in Angular 2 - Sebastian Müller
Sebastian Holstein
 
Building a private CI/CD pipeline with Java and Docker in the Cloud as presen...
Building a private CI/CD pipeline with Java and Docker in the Cloud as presen...
Baruch Sadogursky
 
Angular 2 - Better or worse
Angular 2 - Better or worse
Vladimir Georgiev
 
Angular 2
Angular 2
Travis van der Font
 
Introduction to Angular 2
Introduction to Angular 2
Knoldus Inc.
 
55 New Features in JDK 9
55 New Features in JDK 9
Simon Ritter
 
Angular 2 Crash Course
Angular 2 Crash Course
Elisha Kramer
 
Java Intro: Unit1. Hello World
Java Intro: Unit1. Hello World
Yakov Fain
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and Rx
Sumant Tambe
 
Seven Versions of One Web Application
Seven Versions of One Web Application
Yakov Fain
 
Dart for Java Developers
Dart for Java Developers
Yakov Fain
 
Cours java smi 2007 2008
Cours java smi 2007 2008
Khalil Lechheb
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Codemotion
 
The productive developer guide to Angular 2
The productive developer guide to Angular 2
Maurice De Beijer [MVP]
 
A Designer's Intro to Oracle JET
A Designer's Intro to Oracle JET
Lauren Beatty
 
Angular 4 for Java Developers
Angular 4 for Java Developers
Yakov Fain
 
Angular 2 for Java Developers
Angular 2 for Java Developers
Yakov Fain
 
Angular 2 Essential Training
Angular 2 Essential Training
Patrick Schroeder
 
Building Universal Applications with Angular 2
Building Universal Applications with Angular 2
Minko Gechev
 
Integrating consumers IoT devices into Business Workflow
Integrating consumers IoT devices into Business Workflow
Yakov Fain
 
Data Flow Patterns in Angular 2 - Sebastian Müller
Data Flow Patterns in Angular 2 - Sebastian Müller
Sebastian Holstein
 
Building a private CI/CD pipeline with Java and Docker in the Cloud as presen...
Building a private CI/CD pipeline with Java and Docker in the Cloud as presen...
Baruch Sadogursky
 
Introduction to Angular 2
Introduction to Angular 2
Knoldus Inc.
 
55 New Features in JDK 9
55 New Features in JDK 9
Simon Ritter
 
Angular 2 Crash Course
Angular 2 Crash Course
Elisha Kramer
 
Java Intro: Unit1. Hello World
Java Intro: Unit1. Hello World
Yakov Fain
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and Rx
Sumant Tambe
 
Seven Versions of One Web Application
Seven Versions of One Web Application
Yakov Fain
 
Dart for Java Developers
Dart for Java Developers
Yakov Fain
 
Cours java smi 2007 2008
Cours java smi 2007 2008
Khalil Lechheb
 
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Reactive Programming in Java by Mario Fusco - Codemotion Rome 2015
Codemotion
 
The productive developer guide to Angular 2
The productive developer guide to Angular 2
Maurice De Beijer [MVP]
 
A Designer's Intro to Oracle JET
A Designer's Intro to Oracle JET
Lauren Beatty
 
Ad

Similar to Reactive programming in Angular 2 (20)

Rxjs marble-testing
Rxjs marble-testing
Christoffer Noring
 
Rxjs ngvikings
Rxjs ngvikings
Christoffer Noring
 
Functional Reactive Programming (FRP): Working with RxJS
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
Rxjs swetugg
Rxjs swetugg
Christoffer Noring
 
Rxjs ppt
Rxjs ppt
Christoffer Noring
 
Angular2 rxjs
Angular2 rxjs
Christoffer Noring
 
RxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMix
Tracy Lee
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)
Tracy Lee
 
Rxjs vienna
Rxjs vienna
Christoffer Noring
 
Przywitaj się z reactive extensions
Przywitaj się z reactive extensions
Marcin Juraszek
 
Functional Reactive Programming with RxJS
Functional Reactive Programming with RxJS
stefanmayer13
 
Under the hood of RxJS (Dimitris Livas) - GreeceJS #27
Under the hood of RxJS (Dimitris Livas) - GreeceJS #27
GreeceJS
 
Reactive x
Reactive x
Gabriel Araujo
 
Angular mix chrisnoring
Angular mix chrisnoring
Christoffer Noring
 
Angular observables for fun and profit
Angular observables for fun and profit
Gil Steiner
 
Reactive frontends with RxJS and Angular
Reactive frontends with RxJS and Angular
VMware Tanzu
 
My Gentle Introduction to RxJS
My Gentle Introduction to RxJS
Mattia Occhiuto
 
Observables in Angular
Observables in Angular
Knoldus Inc.
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015
Ben Lesh
 
Luis Atencio on RxJS
Luis Atencio on RxJS
Luis Atencio
 
Functional Reactive Programming (FRP): Working with RxJS
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
RxJS Operators - Real World Use Cases - AngularMix
RxJS Operators - Real World Use Cases - AngularMix
Tracy Lee
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)
Tracy Lee
 
Przywitaj się z reactive extensions
Przywitaj się z reactive extensions
Marcin Juraszek
 
Functional Reactive Programming with RxJS
Functional Reactive Programming with RxJS
stefanmayer13
 
Under the hood of RxJS (Dimitris Livas) - GreeceJS #27
Under the hood of RxJS (Dimitris Livas) - GreeceJS #27
GreeceJS
 
Angular observables for fun and profit
Angular observables for fun and profit
Gil Steiner
 
Reactive frontends with RxJS and Angular
Reactive frontends with RxJS and Angular
VMware Tanzu
 
My Gentle Introduction to RxJS
My Gentle Introduction to RxJS
Mattia Occhiuto
 
Observables in Angular
Observables in Angular
Knoldus Inc.
 
RxJS and Reactive Programming - Modern Web UI - May 2015
RxJS and Reactive Programming - Modern Web UI - May 2015
Ben Lesh
 
Luis Atencio on RxJS
Luis Atencio on RxJS
Luis Atencio
 
Ad

More from Yakov Fain (14)

Type script for_java_dev_jul_2020
Type script for_java_dev_jul_2020
Yakov Fain
 
Web sockets in Angular
Web sockets in Angular
Yakov Fain
 
Using JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 
Using JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 
TypeScript for Java Developers
TypeScript for Java Developers
Yakov Fain
 
Using JHipster 4 for generating Angular/Spring Boot apps
Using JHipster 4 for generating Angular/Spring Boot apps
Yakov Fain
 
Overview of the AngularJS framework
Overview of the AngularJS framework
Yakov Fain
 
RESTful services and OAUTH protocol in IoT
RESTful services and OAUTH protocol in IoT
Yakov Fain
 
Intro to JavaScript
Intro to JavaScript
Yakov Fain
 
Running a Virtual Company
Running a Virtual Company
Yakov Fain
 
Princeton jug git_github
Princeton jug git_github
Yakov Fain
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSockets
Yakov Fain
 
Surviving as a Professional Software Developer
Surviving as a Professional Software Developer
Yakov Fain
 
Becoming a professional software developer
Becoming a professional software developer
Yakov Fain
 
Type script for_java_dev_jul_2020
Type script for_java_dev_jul_2020
Yakov Fain
 
Web sockets in Angular
Web sockets in Angular
Yakov Fain
 
Using JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 
Using JHipster for generating Angular/Spring Boot apps
Using JHipster for generating Angular/Spring Boot apps
Yakov Fain
 
TypeScript for Java Developers
TypeScript for Java Developers
Yakov Fain
 
Using JHipster 4 for generating Angular/Spring Boot apps
Using JHipster 4 for generating Angular/Spring Boot apps
Yakov Fain
 
Overview of the AngularJS framework
Overview of the AngularJS framework
Yakov Fain
 
RESTful services and OAUTH protocol in IoT
RESTful services and OAUTH protocol in IoT
Yakov Fain
 
Intro to JavaScript
Intro to JavaScript
Yakov Fain
 
Running a Virtual Company
Running a Virtual Company
Yakov Fain
 
Princeton jug git_github
Princeton jug git_github
Yakov Fain
 
Speed up your Web applications with HTML5 WebSockets
Speed up your Web applications with HTML5 WebSockets
Yakov Fain
 
Surviving as a Professional Software Developer
Surviving as a Professional Software Developer
Yakov Fain
 
Becoming a professional software developer
Becoming a professional software developer
Yakov Fain
 

Recently uploaded (20)

TrustArc Webinar - 2025 Global Privacy Survey
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc
 
“Why It’s Critical to Have an Integrated Development Methodology for Edge AI,...
“Why It’s Critical to Have an Integrated Development Methodology for Edge AI,...
Edge AI and Vision Alliance
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Oracle Cloud Infrastructure AI Foundations
Oracle Cloud Infrastructure AI Foundations
VICTOR MAESTRE RAMIREZ
 
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Puppy jhon
 
The State of Web3 Industry- Industry Report
The State of Web3 Industry- Industry Report
Liveplex
 
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
Safe Software
 
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
 
PyData - Graph Theory for Multi-Agent Integration
PyData - Graph Theory for Multi-Agent Integration
barqawicloud
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
High Availability On-Premises FME Flow.pdf
High Availability On-Premises FME Flow.pdf
Safe Software
 
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
NTT DATA Technology & Innovation
 
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Alliance
 
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
Safe Software
 
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
angelo60207
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
Kubernetes Security Act Now Before It’s Too Late
Kubernetes Security Act Now Before It’s Too Late
Michael Furman
 
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
Edge AI and Vision Alliance
 
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Safe Software
 
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc Webinar - 2025 Global Privacy Survey
TrustArc
 
“Why It’s Critical to Have an Integrated Development Methodology for Edge AI,...
“Why It’s Critical to Have an Integrated Development Methodology for Edge AI,...
Edge AI and Vision Alliance
 
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
vertical-cnc-processing-centers-drillteq-v-200-en.pdf
AmirStern2
 
Oracle Cloud Infrastructure AI Foundations
Oracle Cloud Infrastructure AI Foundations
VICTOR MAESTRE RAMIREZ
 
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Viral>Wondershare Filmora 14.5.18.12900 Crack Free Download
Puppy jhon
 
The State of Web3 Industry- Industry Report
The State of Web3 Industry- Industry Report
Liveplex
 
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
FME for Good: Integrating Multiple Data Sources with APIs to Support Local Ch...
Safe Software
 
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
No-Code Workflows for CAD & 3D Data: Scaling AI-Driven Infrastructure
Safe Software
 
PyData - Graph Theory for Multi-Agent Integration
PyData - Graph Theory for Multi-Agent Integration
barqawicloud
 
Enabling BIM / GIS integrations with Other Systems with FME
Enabling BIM / GIS integrations with Other Systems with FME
Safe Software
 
High Availability On-Premises FME Flow.pdf
High Availability On-Premises FME Flow.pdf
Safe Software
 
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
Can We Use Rust to Develop Extensions for PostgreSQL? (POSETTE: An Event for ...
NTT DATA Technology & Innovation
 
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Seminar: Perspectives on Passkeys & Consumer Adoption.pptx
FIDO Alliance
 
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
National Fuels Treatments Initiative: Building a Seamless Map of Hazardous Fu...
Safe Software
 
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
Your startup on AWS - How to architect and maintain a Lean and Mean account J...
angelo60207
 
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Seminar: Authentication for a Billion Consumers - Amazon.pptx
FIDO Alliance
 
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance Seminar State of Passkeys.pptx
FIDO Alliance
 
Kubernetes Security Act Now Before It’s Too Late
Kubernetes Security Act Now Before It’s Too Late
Michael Furman
 
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
“Addressing Evolving AI Model Challenges Through Memory and Storage,” a Prese...
Edge AI and Vision Alliance
 
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Integration of Utility Data into 3D BIM Models Using a 3D Solids Modeling Wor...
Safe Software
 

Reactive programming in Angular 2

  • 1. Reactive programming in Angular 2 Yakov Fain yfain
  • 2. About myself • Solutions Architect at Farata Systems • Java Champion • Co-authored the book
 “Angular Development with TypeScript”
  • 3. The Agenda • Intro to RxJS
 
 - Observable
 - Observer
 - Operators • Observables in Angular 2
 
 - Forms
 - Http
 - Router
  • 4. RxJS 5 • Github repo:
 https://github.com/ReactiveX/rxjs • CDN: 
 https://unpkg.com/@reactivex/rxjs/dist/global/Rx.js • Installing RxJS in the npm-based projects:
 
 npm install rxjs • Documentation:
 http://reactivex.io/rxjs 

  • 5. Main RxJS players • Observable - a producer of sequences of values • Observer - a consumer of observable values • Subscriber - connects observer with observable • Operator - en-route value transformation
  • 10. Observable
SubscriberObserver Data
 Source 
 Data Flow next next() error() complete()
  • 11. An Observable allows: • Subscribe/unsubscribe to its data stream • Emit the next value to the observer • Notify the observer about errors • Inform the observer about the stream completion
  • 12. An Observer provides: • A function to handle the next value from the stream • A function to handle errors • A function to handle end-of-stream
  • 13. Creating an Observable • Observable.create() - returns Observable that can invoke methods on Observer • Observable.from() - converts an array or iterable into Observable • Observable.fromEvent() - converts an event into Observable • Observable.fromPromise() - converts a Promise into Observable • Observable.range() - returns a sequence of integers in the specified range
  • 14. An Operator Observable Observable A transforming
 function
  • 15. Let’s have a beer let beers = [
 {name: "Stella", country: "Belgium", price: 9.50},
 {name: "Sam Adams", country: "USA", price: 8.50},
 {name: "Bud Light", country: "USA", price: 6.50},
 {name: "Brooklyn Lager", country: "USA", price: 8.00},
 {name: "Sapporo", country: "Japan", price: 7.50}
 ];

  • 16. An Operator Observable Observable A transforming
 function observableBeers
 .filter(beer => beer.price < 8))
  • 17. observableBeers = Rx.Observable.from(beers)
 .filter(beer => beer.price < 8)
 .map(beer => beer.name + ": $" + beer.price);
 
 observableBeers
 .subscribe(
 beer => console.log(beer),
 err => console.error(err),
 () => console.log("Streaming is over")
 ); Observable Beer Creating the 
 Observable
  • 18. observableBeers = Rx.Observable.from(beers)
 .filter(beer => beer.price < 8)
 .map(beer => beer.name + ": $" + beer.price);
 
 observableBeers
 .subscribe(
 beer => console.log(beer),
 err => console.error(err),
 () => console.log("Stream is over")
 ); Operators Observer Observable Beer
  • 19. observableBeers = Rx.Observable.from(beers)
 .filter(beer => beer.price < 8)
 .map(beer => beer.name + ": $" + beer.price);
 
 observableBeers
 .subscribe(
 beer => console.log(beer),
 err => console.error(err),
 () => console.log("Streaming is over")
 ); Observable Beer No 
 streaming yet Streaming
 begins
  • 24. RX: the data moves across your algorithm
  • 26. Error-handling operators • error() is invoked by the Observable on the Observer. • catch() - intercepts the error in the subscriber before the observer gets it. You can handle the error and re-subscribe.
 • retry(n) - retry immediately up to n times
 • retryWhen(fn) - retries as prescribed by the argument

  • 27. // Declaring function getData(): Observable {…} // data source 1
 function getCachedData(): Observable {…} // data source 2 function getDataFromAnotherService(): Observable {…} // data source 3 //Invoking and subscribing getData()
 .catch(err => { 
 
 if (err.status === 500){
 console.error("Switching to streaming cached beer data");
 return getCachedData();
 } else{
 console.error("Switching to another beer service");
 return getDataFromAnotherService();
 }
 
 })
 .map(beer => beer.name + ", " + beer.country)
 .subscribe(
 beer => console.log("Subscriber got " + beer)
 ); F a i
 l
 o v e
 r Failover with catch() plunker: http://bit.ly/2jXY9ha
  • 29. function getDrinks() {
 
 let beers = Rx.Observable.from([
 {name: "Stella", country: "Belgium", price: 9.50},
 {name: "Sam Adams", country: "USA", price: 8.50},
 {name: "Bud Light", country: "USA", price: 6.50}
 ]);
 
 let softDrinks = Rx.Observable.from([
 {name: "Coca Cola", country: "USA", price: 1.50},
 {name: "Fanta", country: "USA", price: 1.50},
 {name: "Lemonade", country: "France", price: 2.50}
 ]);
 
 return Rx.Observable.create( observer => {
 
 observer.next(beers); // pushing the beer pallet (observable)
 observer.next(softDrinks); // pushing the soft drinks pallet (observable)
 }
 );
 }
 
 getDrinks()
 .flatMap(drinks => drinks) // unloading drinks from pallets
 .subscribe(
 drink => console.log("Subscriber got " + drink.name + ": " + drink.price ) ); plunker http://bit.ly/2jZgc6T Operator flatMap• Handles every value emitted by an observable as another observable • Auto-subscribes to the internal observable and unwraps it
  • 31. Operator concat Subscribe to the next observable only when the previous completes. It’s useful for a sequential processing, e.g. HTTP requests. // Emulate HTTP requests let fourSecHTTPRequest = Rx.Observable.timer(4000).mapTo('First response'); let oneSecHTTPRequest = Rx.Observable.timer(1000).mapTo('Second response'); Rx.Observable .concat(fourSecHTTPRequest, oneSecHTTPRequest) .subscribe(res => console.log(res)); plunker http://bit.ly/2keEoiI
  • 33. Observables in Angular Code samples: https://github.com/yfain/observables
  • 35. An input field: FormControl • valueChanges - the value of the form control changes
 
 this.searchInput.valueChanges.subscribe(…); • statusChanges - status of the form control (valid/invalid)
 
 this.password.statusChanges.subscribe(…);
  • 36. Observable Events in Angular forms @Component({
 selector: "app",
 template: `
 <h2>Observable events demo</h2>
 <input type="text" placeholder="Enter stock" [formControl]="searchInput">
 `
 })
 class AppComponent {
 
 searchInput: FormControl;
 
 constructor(){
 this.searchInput = new FormControl('');
 
 this.searchInput.valueChanges
 .debounceTime(500)
 .subscribe(stock => this.getStockQuoteFromServer(stock));
 }
 
 getStockQuoteFromServer(stock) {
 
 console.log(`The price of ${stock} is ${100*Math.random().toFixed(4)}`);
 }
 } Observable
  • 38. Http and Observables 
 class AppComponent {
 
 products: Array<string> = [];
 
 constructor(private http: Http) {
 
 this.http.get(‘/products')
 .map(res => res.json())
 .subscribe(
 data => {
 
 this.products=data;
 },
 
 err =>
 console.log("Can't get products. Error code: %s, URL: %s ",
 err.status, err.url),
 
 () => console.log('Product(s) are retrieved')
 );
 }
 } O b s e r v e r
  • 39. @Component({
 selector: 'http-client',
 template: `<h1>All Products</h1>
 <ul>
 <li *ngFor="let product of products | async">
 {{product.title}}
 </li>
 </ul>
 <h2>{{errorMessage}}</h2>
 `})
 class AppComponent {
 
 products: Observable<Array<string>>;
 errorMessage: string;
 
 constructor(private http: Http) {
 
 this.products = this.http.get('/products')
 .map(res => res.json())
 .catch( err => {
 this.errorMessage =`Can't get product details from ${err.url},
 error ${err.status} `;
 return Observable.empty();
 });
 }
 } async pipe
  • 40. The switchMap operator RxJS 5, official doc:
 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method- switchMap
 Returns an Observable that emits items based on applying a function that you supply to each item emitted by the source Observable, where that function returns an (so-called "inner") Observable. Each time it observes one of these inner Observables, the output Observable begins emitting the items emitted by that inner Observable. When a new inner Observable is emitted, switchMap stops emitting items from the earlier-emitted inner Observable and begins emitting items from the new one. It continues to behave like this for subsequent inner Observables.
  • 41. The switchMap operator RxJS 5, official doc:
 http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method- switchMap
 Returns an Observable that emits items based on applying a function that you supply to each item emitted by the source Observable, where that function returns an (so-called "inner") Observable. Each time it observes one of these inner Observables, the output Observable begins emitting the items emitted by that inner Observable. When a new inner Observable is emitted, switchMap stops emitting items from the earlier-emitted inner Observable and begins emitting items from the new one. It continues to behave like this for subsequent inner Observables.
  • 42. When a picture worth a thousand words http://reactivex.io/documentation/operators/images/switchMap.png
  • 43. The switchMap operator in English • An outer observable emits the data and switches over to the inner observable for processing • If the outer observable emits the new data while the inner one is still processing, the inner observable is terminated
 • The inner observable starts processing the newly emitted data
 • Example: A user types in a field (outer observable) and the HTTP requests are being made (inner observable) as the user types
  • 44. Killing HTTP requests with switchMap <input type="text" placeholder="Enter city" [formControl]="searchInput"> … this.searchInput.valueChanges
 .debounceTime(200)
 .switchMap(city => this.getWeather(city))
 .subscribe(
 res => {
 this.temperature =
 `Current temperature is ${res.main.temp}F, ` +
 `humidity: ${res.main.humidity}%`; },
 err => console.log(`Can't get weather. Error code: %s, URL: %s`, err.message, err.url)
 );
 }
 
 getWeather(city): Observable<Array> {
 return this.http.get(this.baseWeatherURL + city + this.urlSuffix)
 .map(res => res.json());
 } Outer Obs. Inner Obs.
  • 47. Receiving params in ActivatedRoute • Inject ActivatedRoute into a component to receive route params during navigation • Use ActivatedRoute.snapshot to get params once • Use ActivatedRoute.param.subscribe() for receiving multiple params over time
  • 48. Subject: Observable + Observer Can emit values and allows to subscribe to them @Component({
 selector: "app-root",
 template: `
 <h3>Using Subject for emitting/subscribing to keyup and input events</h3>
 <input type="text" placeholder="Start typing" 
 (input)="mySubject.next($event)" (keyup)="myKeySubject.next($event)">
 `
 })
 export class AppComponent {
 
 mySubject: Observable<Event> = new Subject(); // Observable for any events myKeySubject: Observable<KeyboardEvent> = new Subject(); // Observable for keyboard events
 
 constructor(){
 
 this.myKeySubject.subscribe(({type, key}) => console.log(`Event: ${type} key: ${key}`));
 
 this.mySubject.subscribe(({type, target}) => console.log(
 `Event: ${type} value: ${(<HTMLInputElement>target).value}`));
 }
 }
  • 49. Sharing an Observable @Component({
 selector: "app-root",
 template: `
 <h3>Sharing Observable between subscribers to keyup and input events</h3>
 <input type="text" placeholder="Start typing" 
 (input)="mySubject.next($event)" 
 (keyup)="mySubject.next($event)">
 
 <br> Subscriber to input events got {{inputValue}}
 <p>
 <br> Subscriber to input events got {{keyValue}} 
 `
 })
 export class AppComponent {
 
 keyValue: string;
 inputValue: string;
 
 mySubject: Observable<Event> = new Subject().share(); // Single Observable for any events
 
 constructor(){
 
 // Subscriber 1
 this.mySubject
 .filter(({type}) => type==="keyup")
 .map(e => (<KeyboardEvent>e).key)
 .subscribe((value) => this.keyValue=value);
 
 // Subscriber 2
 this.mySubject
 .filter(({type}) => type==="input")
 .map(e => (<HTMLInputElement>e.target).value)
 .subscribe((value) => this.inputValue=value);
 }
 }
  • 50. @Component({
 selector: "app",
 template: `
 <h2>Sharing the same stream</h2>
 <input #myinput type="text" placeholder="Start typing" > <br> Subscribing to each value: {{data1}}
 <br> Subscribing to 3-second samples: {{data2}}
 `})
 class AppComponent { 
 @ViewChild('myinput') myInputField: ElementRef;
 
 data1: string;
 data2: string;
 
 ngAfterViewInit(){
 
 let keyup$: Observable = Observable.fromEvent(this.myInputField.nativeElement, 'keyup');
 
 let keyupValue$ = keyup$
 .map(event => event.target.value)
 .share();
 
 // Subscribe to each keyup
 keyupValue$
 .subscribe(value => this.data1 = value);
 
 // Subscribe to 3-second samples
 keyupValue$
 .sample(Observable.interval(3000))
 .subscribe(value => this.data2 = value);
 }
 } Accessing native elements with ElementRef Using ElementRef
 is not recommended
  • 52. Subscribing to EventEmitter export declare class EventEmitter<T> extends Subject<T> {} myEvent: EventEmitter<string> = new EventEmitter(); myEvent.emit("Hello World"); … myEvent.subscribe(event => console.log(" Received " + event); Your app: Angular: Has Observer
 and Observable
  • 54. Subscribing to EventEmitter export declare class EventEmitter<T> extends Subject<T> {} myEvent: EventEmitter<string> = new EventEmitter(); myEvent.emit("Hello World"); … myEvent.subscribe(event => console.log(" Received " + event); Your app: Angular:
  • 55. Mediator, DI, Events, and Observables StateService Component1 with injected StateService Component2 with injected StateService EventEmitter Emit event
 on StateService Subscribe to event
 of StateService
  • 58. Wrapping WebSocket into Observable import {Observable } from 'rxjs/Observable';
 
 export class BidService{
 
 ws: WebSocket;
 
 createObservableSocket(url:string): Observable{
 
 this.ws = new WebSocket(url);
 
 return new Observable(
 observer => {
 
 this.ws.onmessage = (event) => observer.next(event.data);
 
 this.ws.onerror = (event) => observer.error(event);
 
 this.ws.onclose = (event) => observer.complete();
 });
 }
 
 }
  • 59. Subscribing to WebSocket’s messages @Component({ … })
 class BidComponent {
 newBid: Bid;
 
 constructor(private wsService: BidService) {
 
 this.wsService.createObservableSocket("ws://localhost:8085")
 .map(res => JSON.parse(res))
 .subscribe(
 data => {
 
 this.newBid = data;
 this.newBid.bidTime= Date.parse(data.bidTime);
 console.log(this.newBid);
 },
 err => console.log( err),
 () => console.log( 'The bid stream is complete')
 );
 }
 
 }
  • 60. Demo1. Open http_websocket_samples
 2. systemjs.config: bids/bid-component.ts 3. npm run tsc
 
 4.npm run bidServer
 
 5.http://localhost:8000
  • 61. Summary • Everything is an observable • No data is pushed to you until you subscribe • Chain the operators to pre-process the observable data before it gets to the subscriber • Angular offers you ready-to-use observables in multiple components and services • You can wrap the data pushed to your app into an Observable
  • 62. Thank you! • Code samples:
 https://github.com/yfain/observables • Training inquiries: 
 [email protected] • My blog:
 yakovfain.com • Twitter: @yfain