Transcript
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!