add some fun to your functional programming with rxjs
DESCRIPTION
Slides from my 2014 MounainWestJS talk "Add some Fun to Your Functional Programming With RXJS"TRANSCRIPT
![Page 1: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/1.jpg)
Add some FUN to your Functional programming
with RXJS
![Page 2: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/2.jpg)
Java…Groovy…
and JavaScript
Senior UI Engineer at NetflixWe do a lot of RX stuff with…
About Me
![Page 3: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/3.jpg)
bittersweetryan
About Me
![Page 4: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/4.jpg)
Before We Begin
![Page 5: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/5.jpg)
Before We Begin
Be KIND to those of us with OCD and…
![Page 6: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/6.jpg)
Before We Begin
Change those Dropbox icons to B&W!
![Page 7: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/7.jpg)
Functional Review!(With an RX twist)
![Page 8: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/8.jpg)
Functional Review
Map
ReduceFilter
Zip
![Page 9: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/9.jpg)
var searchResultsSets = keyups. map( function( key ){ return Observable.getJSON('/search?' + input.value) });
Functional Review
Map - Transforms data
![Page 10: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/10.jpg)
var searchResultsSets = keyups. filter( function ( key ){ return input.value.length > 1; }). map( function( key ){ return Observable.getJSON('/search?' + input.value) );
Functional Review
Filter - Narrows Collections
![Page 11: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/11.jpg)
var html = searchResultsSets. reduce(function( prev,curr ) { return prev + '<li>' + curr.name + '</li>'; },'' );
Functional Review
Reduce - Turns a collection into a single value
![Page 12: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/12.jpg)
Functional Review
Zip - Combines two collections
var movies = [ 'Super Troopers', 'Pulp Fiction', 'Fargo' ] ; var boxArts =[ '/cdn/23212/120x80', '/cdn/73212/120x80','/cdn/99212/120x80' ] ; !var withArt = Observable. zip(movies, boxarts, function(movie, boxart){ return {title : movie, boxart : boxart}; }); !//[{title : 'Super Troo…', boxart : '/cdn…'}, // {title : 'Pulp Fict…', boxart : '/cdn…' }, // {title : 'Fargo', boxart : 'cdn…' } ]
![Page 13: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/13.jpg)
Functional Review
Observable Data Streams Are Like Crazy Straws
keyPresses Observable
forEach
throttlefilter
mapdistinctUntilChanged
reduce
![Page 14: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/14.jpg)
Thinking Functionally!!
![Page 15: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/15.jpg)
Thinking Functionally
Replace loops with map, reduce, and filter.
searchResults = Observable. getJSON(‘/people?’ + input.value); !searchResults. forEach( function( reps ){ var names = []; for( var i = 1; i < resp; i++ ){ var name = data[i].fName + ' ' + data[i].lName; names.push( name ); } });
![Page 16: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/16.jpg)
Thinking Functionally
Replace loops with map and reduce.
searchResults = Observable. getJSON(‘/people?’ + input.value). map( function( data ){ return data.fName + data.lName; } ); !searchResults.forEach( function( resp ){ //resp will now be the names array })
![Page 17: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/17.jpg)
Thinking Functionally
Replace if’s with filters.
var keyPresses = O.fromEvent( el, 'keyup' ) !keyPresses.forEach( function( e ){ if( e.which === keys.enter ){ //=> no! //do something } });
![Page 18: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/18.jpg)
Thinking Functionally
Replace if’s with filters.
var enterPresses = O.fromEvent( el, 'keyup' ) .filter( function( e ){ return e.which && e.which === keys.enter; }); !enterPresses.forEach( function( e ){ //do something });
![Page 19: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/19.jpg)
Thinking Functionally
Don’t put too much in a single stream.
var submits = O.fromEvent(input,'keypresses'). throttle(). map( function( e ){ return e.which } ). filter( function( key ){ return key === keys.enter || keys.escape; }). map(). reduce(). ...
Smaller streams are OK.
![Page 20: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/20.jpg)
Thinking Functionally
var submits = Observable.fromEvent(input,'keypresses'). throttle(). map( function( e ){ return e.which } ); !var enters = submits.filter( function( key ) ){ return e.which === keys.enter; } !var escapes = submits.filter( function( key ) ){
Don’t put too much in a single stream.Smaller streams are OK.
![Page 21: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/21.jpg)
Flattening Patterns!managing concurrency!
![Page 22: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/22.jpg)
Observables = Events Over Time
Key presses over time…
.5s 1s 1.5s 2s 2.5s 3s
B R E A K IJ <- N G B A D
![Page 23: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/23.jpg)
Observables = Events Over Time
1s 2s 3s 4s 5s 6s
BR
BRE
BREAK
BREAKJ
BREAKING
BREAKING BA
BREAKING BAD
Ajax requests over time…
![Page 24: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/24.jpg)
The Three Musketeers
Goofy as merge
Donald as concat
Mickey as switchLatest
Starring
![Page 25: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/25.jpg)
Flattening Patterns
merge - combines items in a collection as each item arrives
concat - combines collections in the order they arrived
switchLatest - switches to the latest collection that ! arrives
![Page 27: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/27.jpg)
Concat
1s 2shttp://jsbin.com/fejod/4/edit
!
!
data
data
data
data
![Page 28: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/28.jpg)
SwitchLatest
!
1s 2s
data
data
data
data
![Page 29: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/29.jpg)
Building Animated AutoComplete!
Putting Everything Together
![Page 30: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/30.jpg)
Animated Autocomplete
SearchBBrBreaking Bad Bridezillas Brothers & Sisters The Breakfast Club Brother Bear
Breaking Bad The Breakfast Club Breakout Kings Breaking Dawn Breaking Amish
BreBreaBreak
![Page 31: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/31.jpg)
Observables = Events Over Time
Simple Widget, High Complexity• Respond to key presses
• Send off Ajax requests
• Animate out when search results become invalid
• Animate in when new search results come in
• Don’t show old results
• Make sure one animation is finished before starting another
![Page 32: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/32.jpg)
var keyups = Observable. fromEvent( searchInput, 'keypress');
Animated Autocomplete
![Page 33: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/33.jpg)
var searchResultsSets = keyups. filter( function ( e ){ return input.value.length > 1; }). map( function( e ){ return Observable. getJSON('/search?' + input.value); }). switchLatest();
Animated Autocomplete
![Page 34: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/34.jpg)
var animateOuts = keyups. map(function( resultSet ){ return animateOut(resultsDiv); }); !var animateIns = searchResultsSets. map( function( resultSet ){ return Observable. of(resultsSet). concat(animateIn(resultsDiv)); });
Animated Autocomplete
![Page 35: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/35.jpg)
var resultSets = animateOuts. merge(animateIns). concatAll(); !resultSets. forEach( function( resultSet ){ if (resultSet.length === 0) { $('.search-results').addClass('hidden'); } else { resultsDiv.innerHTML = toHTML(resultSet ); } } );
Animated Autocomplete
![Page 36: Add Some Fun to Your Functional Programming With RXJS](https://reader034.vdocument.in/reader034/viewer/2022052504/554a108bb4c9058c5d8b4a57/html5/thumbnails/36.jpg)
var keyups = Observable. fromEvent( searchInput, ‘keypress'); !var searchResultsSets = keyups. filter( function ( e ){ return input.value.length > 1; }). map( function( e ){ return Observable. getJSON('/search?' + input.value); }). switchLatest(); var animateOuts = keyups. map(function( resultSet ){ return animateOut(resultsDiv); }); !var animateIns = searchResultsSets. map( function( resultSet ){ return Observable. of(resultsSet). concat(animateIn(resultsDiv)); }); !var resultSets = animateOuts. merge(animateIns). concatAll(); !resultSets. forEach( function( resultSet ){ if (resultSet.length === 0) { $('.search-results').addClass('hidden'); } else { resultsDiv.innerHTML = toHTML(resultSet ); } } );
Animated Autocomplete