37
Add some FUN to your Functional programming with RXJS

Add Some Fun to Your Functional Programming With RXJS

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Add Some Fun to Your Functional Programming With RXJS

Add some FUN to your Functional programming

with RXJS

Page 2: Add Some Fun to Your Functional Programming With RXJS

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

bittersweetryan

About Me

Page 4: Add Some Fun to Your Functional Programming With RXJS

Before We Begin

Page 5: Add Some Fun to Your Functional Programming With RXJS

Before We Begin

Be KIND to those of us with OCD and…

Page 6: Add Some Fun to Your Functional Programming With RXJS

Before We Begin

Change those Dropbox icons to B&W!

Page 7: Add Some Fun to Your Functional Programming With RXJS

Functional Review!(With an RX twist)

Page 8: Add Some Fun to Your Functional Programming With RXJS

Functional Review

Map

ReduceFilter

Zip

Page 9: Add Some Fun to Your Functional Programming With RXJS

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

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

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

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

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

Thinking Functionally!!

Page 15: Add Some Fun to Your Functional Programming With RXJS

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

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

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

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

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

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

Flattening Patterns!managing concurrency!

Page 22: Add Some Fun to Your Functional Programming With RXJS

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

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

The Three Musketeers

Goofy as merge

Donald as concat

Mickey as switchLatest

Starring

Page 25: Add Some Fun to Your Functional Programming With RXJS

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 26: Add Some Fun to Your Functional Programming With RXJS

Merge

1s 2shttp://jsbin.com/wehusi/13/edit

data

data

data

data

Page 27: Add Some Fun to Your Functional Programming With RXJS

Concat

1s 2shttp://jsbin.com/fejod/4/edit

!

!

data

data

data

data

Page 28: Add Some Fun to Your Functional Programming With RXJS

SwitchLatest

!

1s 2s

data

data

data

data

Page 29: Add Some Fun to Your Functional Programming With RXJS

Building Animated AutoComplete!

Putting Everything Together

Page 30: Add Some Fun to Your Functional Programming With RXJS

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

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

var keyups = Observable. fromEvent( searchInput, 'keypress');

Animated Autocomplete

Page 33: Add Some Fun to Your Functional Programming With RXJS

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

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

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

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

Page 37: Add Some Fun to Your Functional Programming With RXJS

Thank You.!!

[email protected]@bittersweetryan!