Project setup
Part III: The Demo
Congratulations!
You are a pioneer.
These tecniques are new to the javascript ecosystem.
Libraries are evolving
We’ll combine the best ones
• CrossEye / ramda • baconjs / bacon.js -> handles the streams stuff • fantasyland / fantasy-io -> it's a spec to tell you how to name your functions etc. • DrBoolean / pointfree-fantasy -> makes it easier to do pointfree composition stuff • folktale / data.either -> there's a big overlap with ramda, but for now it adds some extra utils
https://github.com/DrBoolean/hardcorejs https://vimeo.com/97575933
His GitHub repo for the demo app. : begriffs/immutube
Starts with Blank State commit
The important things happen in app.js. First shows the interface. It's one empty input box. The goal is that as you type, youtube search results pop up. And you can click on the video to play. It's all client side. He still needs a server to be able to do cross server calls in Chrome (cannot do it if you just open the html file in Chrome).
/* global define */
define([
'jquery'
, 'ramda'
, 'pointfree'
, 'Maybe'
, 'player'
, 'bacon'
], function($, _, P, Maybe, Player, bacon) {
'use strict';
// HELPERS ///////////////////////////////////////////////////////////////////////////
var compose = P.compose;
var map = P.map;
var log = function(x) { console.log(x); return x; }
var fork = _.curry(function(f, future) { return future.fork(log, f); })
var setHtml = _.curry(function(sel, x) { return $(sel).html(x); });
// PURE //////////////////////////////////////////////////////////////////////////////
// IMPURE ////////////////////////////////////////////////////////////////////////////
});
Then start coding
/* global define */
define([
...
], function($, _, P, Maybe, Player, bacon) {
'use strict';
// **** 6. Add and extend io
io.extendFn()
// HELPERS ///////////////////////////////////////////////////////////////////////////
var compose = P.compose;
var map = P.map;
var log = function(x) { console.log(x); return x; }
var fork = _.curry(function(f, future) { return future.fork(log, f); })
var setHtml = _.curry(function(sel, x) { return $(sel).html(x); });
// PURE //////////////////////////////////////////////////////////////////////////////
// **** 3. change the order of arguments for bacon for currying
// we want the order of arguments when we curry,
// so that the first argument should be what we know,
// and what we don't know come last
var listen = _.curry(function (type, elt) {
return Bacon.fromEventTarget(elt, type)
})
// **** 1.
// (attaching an event listener to the DOM is pure)
// (because it won't run anything here)
// getDom :: String -> IO Dom
var getDom = $.toIO()
// (using jQuery)
// **** 2. then ad click (type) listener/handling
// keypressStream :: DOM -> EventStream DomEvent
var keypressStream = listen('keyup')
// IMPURE ////////////////////////////////////////////////////////////////////////////
// **** 4. let's log out
// compose(map(map(log)), map(keypressStream), getDom('#search'))
// **** 5. or after some debate use this form instead of above line:
getDom('#search').map(keypressStream).runIO().onValue
// **** 7. just get the current value of the input target value
// (logging out the key event works at this point)
// cont.. next note
});