13. You have problems with connectivity
Your data behaves more like a continuous stream of
data than Request/Response
Essentially: your Async code starts to look messy
and/or consists of a lot of endpoints with data that
looks and behaves diïŹerently.
4 . 2
18. Think of an Observable as a combination of an Array
and a Promise
5 . 2
19. Array
Promise
list
.map( x = > x.prop )
.filter( x => x > 2 )
.take( 2 )
getData()
.then(
data => console.log(data),
err => console.error(error)
)
5 . 3
20. Observable
let stream$ = Rx.Observable.of({prop: 1},{prop: 2},{prop: 3});
stream$
.map( x => x.prop)
.filter( x => x > 2 )
.take( 2 )
.subscribe(
data => console.log(data),
err => console.error(error)
)
5 . 4
21. Observable = Array + Promise + Cancelling + Retry and
more =
Superpowers
5 . 5
22. An Observable is a function that takes an observer
as an argument
An observer is an object with the methods
Example
.next()
.error()
.complete()
Rx.Observable.create(observer => {
observer.next(1)
observer.error('err')
observer.complete()
});
5 . 6
39. do - use to debug, can be placed where you need it.
Rx.Observable
.of( 1,2,3 )
.do( x => console.log(x) )
.map( x => x +1 )
.filter( x => x % 2 === 0 )
.do( x => console.log(x) )
7 . 8
40. flatMap, sometimes you need to create an Observable
inside an Observable. example: Based on a keyup we
want to do an ajax call
PROBLEM : we get a list of Observables instead of 1
Observable
Rx.Observable.fromEvent(document,'keyup')
.map(ev => event.target.value)
.map( key => {
return Rx.DOM.json(url)
})
7 . 9
41. SOLUTION: flatMap
Creates a metastream instead of a list of Observables
Rx.Observable.fromEvent(document,'keyup')
.map(ev => event.target.value)
.flatMap( key => {
return Rx.DOM.json(url)
})
7 . 10
42. Sometimes `flatMap` is a bad match. You want to be
able to abandon what you were doing if precondition
change. Example a dependent call chain
7 . 11
43. This ensures the rest is thrown away if the user
changes
Rx.Observable.fromEvent(document,'keyup')
.map(ev => ev.target.value)
.switchMap(getUser)
.switchMap(getOrdersByUser)
.switchMap(getProductsByOrder)
7 . 12
46. Requirements
Listen for keyboard presses
Only do server trip a er x number of characters are
entered
Do ajax call based on filtered input
Cash responses
8 . 3
76. We loose last stream because a stream failed before it,
order matters
Rx.Observable.merge(
Rx.Observable.of(1,2,3),
Rx.Observable.throw('err')
Rx.Observable.of(4,5)
)
.subscribe(
data => console.log(data), // 1,2,3
err => console.error(err), // err
() => console.log('completed') // not reached
)
10 . 10
81. Postpone when the error callback is called
Rx.Observable.create(observer => {
observer.next( 1 );
throw { message : 'err' }
})
.retry(5) // times
.subscribe(
data => console.log(data),
err => console.log(err), // hit after 5 retry attempts
() => console.log('completed')
)
10 . 15
82. For 'shaky connections where you expect to succeed
eventually
Whole stream is retried if error is thrown
let stream$ = doAjax()
.retryWhen( errors => {
return errors.delay(200);
})
stream$.subscribe( data => console.log(data));
10 . 16
97. In summary
RxJS shines when your Async is complex
Observables can be created from almost any async
concept
Enables rich composition
Observables are easy to retry
RxJS is easily tested by using Marble Testing
Cancellation is easy, and you should
cancel/unsubscribe, to clean up resources
It's not ketchup, use it where appropriate
12 . 1
99. angular.io/resources "Rxjs Ultimate" - my free book
http://reactivex.io/rxjs/ - OïŹicial documentation
TRy out your snippets with RxFiddle.net
12 . 3