2. What is Functional Reactive Programming (FRP)?
• 1) Functional programming:
• is more declarative
• often has more abstraction
• can involve higher order functions
• 2) Reactive Programming was introduced in 1997:
“programming with asynchronous data streams”
• Multiple toolkits/libraries available
• Supported languages JS, Java, Scala, Android, Swift, Go, ....
NB: Elm is an FRP language: http://elm-lang.org/
3. What is Functional Reactive Programming (FRP)?
A) Functional Reactive Programming:
• a programming paradigm that was created by Conal Elliott
• his definition has very specific semantics:
• https://stackoverflow.com/questions/1028250/what-is-
functional-reactive-programming
B) looser definition of FRP: a combination of 2 other concepts:
• Reactive Programming: focuses on asynchronous data streams,
which you can listen to and react accordingly
• Functional Programming: emphasizes calculations via
mathematical-style functions, immutability and expressiveness,
and minimizes the use of variables and state
4. Popular Toolkits/Libraries for FRP
• RxJS:
https://github.com/Reactive-Extensions/RxJS
• Bacon.js:
https://baconjs.github.io/
• Kefir.js:
https://rpominov.github.io/kefir/
• most.js:
https://github.com/cujojs/most
5. Promises versus RxJS
• "Promises are good for solving asynchronous
operations such as querying a service with an
XMLHttpRequest, where the expected behavior is
one value and then completion.”
• "RxJS unifies both the world of Promises, callbacks
as well as evented data such as DOM Input, Web
Workers, Web Sockets.”
• Support for Web Sockets in RxJS version 5(?)
6. How You can Use Observables in RxJS
• Orchestrate asynchronous data streams
• handle streams of data of indeterminate length
• Respond to mouse events and button clicks
• Generate SVG graphics/animation
• Combine with Promises (Rx.Observable.fromPromise())
• integrate with Angular 2, jQuery, …
7. A Vague Description of some Parts of FRP
• Obtain streams of data from many sources:
an array, list, function, website, ...
• define the required operations via operators
• operators include: map() and filter()
• method chaining of operators is supported
• invoke subscribe() to “make it happen”
8. Using ‘map’ and ‘filter’ (WITHOUT FRP)
• var source = [0,1,2,3,4,5,6,7,8,9,10];
• var result1 = source.map(x => x*x)
• .filter(x => x % 5 == 0);
• console.log("result1: "+result1);
• // output=?
• var result2 = source.filter(x => x % 5 == 0)
• .map(x => x*x)
• // output=?
• Q: what is the difference between these two?
10. JavaScript Files for some Operators in RxJS
• <script
src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.tim
e.js">
• </script>
• <script
src="http://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.coi
ncidence.js">
• </script>
• <script src="http://cdnjs.cloudflare.com/ajax/libs/rxjs-
dom/2.0.7/rx.dom.js">
• </script>
11. What are Observables?
• Think of them as “streams” or sets
• Can comprise any number of items (arbitrary time)
• They generate values when they are “subscribed”
• Can be cancelled and restarted
• their purpose is to avoid “callback hell”
• “unsubscribe” will “tear down” a producer
12. How do Observables Work?
• Let x = Rx.Observable.(...)
• Let result = x.subscribe(valueFn, errorFn, CompleteFn)
• Do various things here...
• result.unsubscribe();
13. Observable Creation in RxJS
Observable.of(...)
Observable.from(promise/iterable/observable);
Observable.fromEvent(...)
Observables from HTTP in Angular 2
Additional RxJS modules/libraries
14. Operators in Observables
+ Operators are methods in Observables
+ Operators allow you to compose new observables
+ Create custom operators based on RxJS operators:
Rx.Observable.prototype.myGreatOperator = ....
General syntax of Observable operators:
let obs = Rx.Observable
.firstOperator()
.secondOperator()
.evenMoreOperatorsIfYouWant()
.subscribe(....); // now stuff happens=
Result:
obs is an Observable “connected” to a source
15. Using Observable, ‘range’, and ‘filter’ in RxJS
• var source = Rx.Observable
• .range(0, 20)
• .filter(x => x < 4)
• //output=?
• var source = Rx.Observable
• .range(0, 20)
• .filter(x => x < 4)
• .subscribe(x => console.log("x = "+x))
• //output=?
// ObservableRangeFilter1.html
17. Using ‘from’ and ‘map’ in RxJS (2b)
var x = Rx.Observable
• .from(['a1','a2','a3'])
• .map((item) => {
• item = item.toUpperCase()+item;
• return item;
• })
x.subscribe(str => console.log("item: "+str));
// output:
A1a1
A2a2
A3a3
18. Observables: Exercises #1
• Modify ObservableMapUpper1.html in the exercises
1) Display the array elements in reverse order
2) Prepend the terminal digit and generate this output:
1a1, 2a2, 3a3
3) Concatenate the elements of the input array
19. Using ‘interval’, ‘take’, and ‘map’ in RxJS (3a)
// ObservableTake.html
var source = Rx.Observable
.interval(1000)
.take(4)
.map(i => ['1','2','3','4','5'][i]);
var result = source.subscribe(x => console.log("x = "+x));
// output =?
20. Using ‘interval’, ‘take’, and ‘map’ in RxJS (3b)
var source2 = Rx.Observable
.interval(1000)
.take(4)
.map(i => ['1','2','3','4','5'][i]);
var subscription = source2.subscribe(
x => console.log('source2 onNext: %s', x),
e => console.log('source2 onError: %s', e),
() => console.log('source2 onCompleted'));
• // output =?
21. Using ‘interval’, ‘take’, and ‘map’ in RxJS (3c)
• Output from BOTH observables is interleaved:
• x = 1
• source2 onNext: 1
• x = 2
• source2 onNext: 2
• x = 3
• source2 onNext: 3
• x = 4
• source2 onNext: 4
• source2 onCompleted
22. Observables: Exercises #2
• Modify ObservableTake.html in the exercises
1) Change the second 1000 to 500 and predict the outcome
2) Emit only even numbers from the first Observable
3) Compute squares of odd numbers in the second
Observable
23. Modify HTML Content via Observables (1)
// ObservableDivElement1.html
<div id="div1">This is a DIV element</div>
<script>
• let div1 = document.querySelector('#div1')
• var stream = Rx.Observable
• .interval(500)
• .take(10)
• .map(x => x*x)
• .subscribe(x => div1.innerHTML += x);
</script>
24. Modify HTML Content via Observables (2)
// ObservableDivElement2.html
<div id="div1">This is a DIV element</div>
<div id="div2">This is a DIV element</div>
<script>
let div1 = document.querySelector('#div1')
let div2 = document.querySelector('#div2')
var stream = Rx.Observable
.interval(500)
.take(10)
.map(x => x*x)
.subscribe(x => {
div1.innerHTML += x;
div2.innerHTML += x;
})
</script>
25. Observables and SVG Graphics/Animation
1) Observables and SVG graphics:
// SVGObservables1.html
2) Observables and SVG animation:
// SVGObservables1Anim1.html
3) Observables and SVG “follow the mouse”:
// SVGObservables1MouseMove1.html
4) Rxjs and SVG graphics/animation:
https://github.com/ocampesato/rxjs-svg-graphics
26. Some Available Operators
map() <= we’ve seen this in Angular 2
filter() <= we’ve seen this in Angular 2
reduce()
first()
last()
take()
skip()
toArray()
isEmpty()
startWith()
27. Observables: Exercises #3
• Modify: ObservableMapUpper1.html
1) Create an Observable with the first() operator
2) Create an Observable with the last() operator
3) What does this Observable emit:
var source = Rx.Observable
.return(8)
.startWith(1, 2, 3)
.subscribe(x => console.log("x = "+x));
30. Map-Related Operators
• map(): items of the observable are mapped or
transformed into something else
• flatMap() (several variants): takes a function
returning an observable from each item of the source
observable, which produces makes a stream of
streams (where stream = observable = sequence of
items), and is "flattened" into a single stream /
observable by flapMap
• flatMapLatest(): a flatMap where only the items of
the current observable are emitted: if a new
observable appears, then the values of the previous
observable are ignored.
31. Map-Related Operators
• concatMap(): uses concat() so that intermediate
results are not 'interleaved', which can happen
with flatMap() because the latter uses merge()
• merge(): combine multiple Observables into one
(interleaving can occur)
• concat(): combine multiple Observables
sequentially into one (no interleaving occurs)
32. Observables: Exercises #4 (self-study)
1) Create an Observable with the merge() operator
2) Create an Observable with the zip() operator
3) Create an Observable with the concat() operator
33. “Hot” versus “Cold” Observables
“cold” observables:
a new producer for each consumer
similar to watching a recorded movie
“hot” observables:
one producer for many consumers
similar to watching a live stream
invoke “publish” to make an observable “hot”
=> all observables are “cold” by default
34. From Promises to Observables
// define a Promise:
var p = new Promise();
// define an Observable from the Promise p:
var x = Observable.fromPromise(p);
// do something with x ...
37. Creating an Observable in v5
let obs = new Observable(observer => {
myAsyncMethod((err,value) => {
if(err) {
observer.error(err);
} else {
observer.next(value); // older v4: onNext
observer.complete(); // older v4: onComplete
}
});
});
NB: ‘on’ prefix has been dropped in v5
38. Further Samples and Reading
1) Create a toggle button with RxJS:
https://www.themarketingtechnologist.co/create-a-
simple-toggle-button-with-rxjs-using-scan-and-startwith/
2) RxJS and mouse events:
http://jsfiddle.net/dinkleburg/ay8afp5f
3) http://reactivex.io/learnrx/
4) http://rxmarble.com
5) http://cycle.js.org/basic-examples.html
39. Recent/Upcoming Books and Training
1) HTML5 Canvas and CSS3 Graphics (2013)
2) jQuery, CSS3, and HTML5 for Mobile (2013)
3) HTML5 Pocket Primer (2013)
4) jQuery Pocket Primer (2013)
5) HTML5 Mobile Pocket Primer (2014)
6) D3 Pocket Primer (2015)
7) Python Pocket Primer (2015)
8) SVG Pocket Primer (2016)
9) CSS3 Pocket Primer (2016)
10) Angular 2 Pocket Primer (2016)