Your SlideShare is downloading. ×
Add Some Fun to Your Functional Programming With RXJS
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Add Some Fun to Your Functional Programming With RXJS

1,546
views

Published on

Slides from my 2014 MounainWestJS talk "Add some Fun to Your Functional Programming With RXJS"

Slides from my 2014 MounainWestJS talk "Add some Fun to Your Functional Programming With RXJS"

Published in: Technology

0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,546
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
13
Comments
0
Likes
7
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Add some FUN to your Functional programming with RXJS
  • 2. Java… Groovy… and JavaScript Senior UI Engineer at Netflix We do a lot of RX stuff with… About Me
  • 3. bittersweetryan About Me
  • 4. Before We Begin
  • 5. Before We Begin Be KIND to those of us with OCD and…
  • 6. Before We Begin Change those Dropbox icons to B&W!
  • 7. Functional Review! (With an RX twist)
  • 8. Functional Review Map Reduce Filter Zip
  • 9. var searchResultsSets = keyups. map( function( key ){ return Observable.getJSON('/search?' + input.value) }); Functional Review Map - Transforms data
  • 10. 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
  • 11. var html = searchResultsSets. reduce(function( prev,curr ) { return prev + '<li>' + curr.name + '</li>'; },'' ); Functional Review Reduce - Turns a collection into a single value
  • 12. 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…' } ]
  • 13. Functional Review Observable Data Streams Are Like Crazy Straws keyPresses Observable forEach throttle filter map distinctUntilChanged reduce
  • 14. Thinking Functionally! !
  • 15. 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 ); } });
  • 16. 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 })
  • 17. 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 } });
  • 18. 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 });
  • 19. 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.
  • 20. 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.
  • 21. Flattening Patterns! managing concurrency!
  • 22. 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
  • 23. Observables = Events Over Time 1s 2s 3s 4s 5s 6s BR BRE BREAK BREAKJ BREAKING BREAKING BA BREAKING BAD Ajax requests over time…
  • 24. The Three Musketeers Goofy as merge Donald as concat Mickey as switchLatest Starring
  • 25. 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
  • 26. Merge 1s 2s http://jsbin.com/wehusi/13/edit data data data data
  • 27. Concat 1s 2s http://jsbin.com/fejod/4/edit ! ! data data data data
  • 28. SwitchLatest ! 1s 2s data data data data
  • 29. Building Animated AutoComplete! Putting Everything Together
  • 30. Animated Autocomplete SearchBBrBreBreaBreak
  • 31. 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
  • 32. var keyups = Observable. fromEvent( searchInput, 'keypress'); Animated Autocomplete
  • 33. var searchResultsSets = keyups. filter( function ( e ){ return input.value.length > 1; }). map( function( e ){ return Observable. getJSON('/search?' + input.value); }). switchLatest(); Animated Autocomplete
  • 34. var animateOuts = keyups. map(function( resultSet ){ return animateOut(resultsDiv); }); ! var animateIns = searchResultsSets. map( function( resultSet ){ return Observable. of(resultsSet). concat(animateIn(resultsDiv)); }); Animated Autocomplete
  • 35. 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
  • 36. 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
  • 37. Thank You.! ! ranklam@netflix.com
 @bittersweetryan!