Skip to content

Instantly share code, notes, and snippets.

@andersonleite
Created January 3, 2017 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andersonleite/bfa671fcf8d3166d06e41d9b2aaa4227 to your computer and use it in GitHub Desktop.
Save andersonleite/bfa671fcf8d3166d06e41d9b2aaa4227 to your computer and use it in GitHub Desktop.
const {div, li, img, h, h2, p, a, makeDOMDriver} = CycleDOM;
function intent(DOMSource) {
// Create streams for the intents that will be observed
const refreshClickStream$ = DOMSource.select('.refresh').events('click');
const close1ClickStream$ = DOMSource.select('.close1').events('click');
const close2ClickStream$ = DOMSource.select('.close2').events('click');
const close3ClickStream$ = DOMSource.select('.close3').events('click');
// Return all the streams ready to be subscribed
return {refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$};
}
function createSuggestionStream(refreshClickStream, responseStream, closeClickStream) {
return closeClickStream.startWith('startup click')
.combineLatest(responseStream,
function(click, listBeers) {
return listBeers[Math.floor(Math.random()*listBeers.length)];
}
)
.merge(
refreshClickStream.map(function(){
return null;
})
)
.startWith(null);
}
// Update UI elements every time somethign is streamed
function renderSuggestion(suggestedBeer, selector) {
var suggestionEl = document.querySelector(selector);
if (suggestedBeer != null) {
suggestionEl.style.visibility = 'visible';
var usernameEl = suggestionEl.querySelector('.username');
usernameEl.textContent = suggestedBeer.name;
var imgEl = suggestionEl.querySelector('img');
imgEl.src = suggestedBeer.image_url;
var descriptionEl = suggestionEl.querySelector('.description');
descriptionEl.textContent = suggestedBeer.description;
}
}
// Subscribe the observers to API results
function model(refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$) {
var requestStream = refreshClickStream$.startWith('startup click')
.map(function() {
return 'https://api.punkapi.com/v2/beers';
});
var responseStream = requestStream
.flatMap(function(requestUrl) {
return Rx.Observable.fromPromise($.getJSON(requestUrl));
});
var suggestion1Stream = createSuggestionStream(refreshClickStream$, responseStream, close1ClickStream$);
var suggestion2Stream = createSuggestionStream(refreshClickStream$, responseStream, close2ClickStream$);
var suggestion3Stream = createSuggestionStream(refreshClickStream$, responseStream, close3ClickStream$);
suggestion1Stream.subscribe(function(suggestedBeer) {
renderSuggestion(suggestedBeer, '.suggestion1');
});
suggestion2Stream.subscribe(function(suggestedBeer) {
renderSuggestion(suggestedBeer, '.suggestion2');
});
suggestion3Stream.subscribe(function(suggestedBeer) {
renderSuggestion(suggestedBeer, '.suggestion3');
});
return responseStream.merge(suggestion1Stream)
.merge(suggestion2Stream)
.merge(suggestion3Stream);
}
// Render the view
function view(state$) {
return state$.map(state =>
div([
div('.info', [
p('Developed by Anderson Leite using RxJS and Cycle.js'),
p('See the 3 part blog post')
]),
div('.header', [
h2('Brewdog\'s beer'),
a('.refresh', {href: '#'}, 'refresh')
]),
div('.containerx', [
div('.left .box', [
h('li.suggestion1', [
div('.beer', [
img()
]),
p('.username', 'loading...'),
p('.description', 'loading...'),
a('.close .close1', {href: '#'}, 'show me other')
])
]),
div('.middle .box', [
h('li.suggestion2', [
div('.beer', [
img()
]),
p('.username', 'loading...'),
p('.description', 'loading...'),
a('.close .close2', {href: '#'}, 'show me other')
])
]),
div('.right .box', [
h('li.suggestion3', [
div('.beer', [
img()
]),
p('.username', 'loading...'),
p('.description', 'loading...'),
a('.close .close3', {href: '#'}, 'show me other')
])
])
])
])
)
}
function main(sources) {
const {refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$} = intent(sources.DOM);
const state$ = model(refreshClickStream$, close1ClickStream$, close2ClickStream$, close3ClickStream$);
const vtree$ = view(Rx.Observable.of(''));
return {
DOM: vtree$
};
}
const drivers = {
DOM: makeDOMDriver('#app')
};
Cycle.run(main, drivers);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment