SlideShare a Scribd company logo
Cycle.js
Who am I?
Arye Lukashevski
Software Engineer @ Wix.com
Intro
What’s Reactive programming?
Foo depends on Bar
But who owns the relationship?
Foo Bar
Proactive
• Foo invokes the action
• Bar has an API for interaction
• ‘Find usages’
Foo Bar
Proactive Passive
function	onClick()	{	
	Bar.increment();	
}	
Foo
Foo Bar
Listenable Reactive
Foo.addSub('click',	()	=>	{	
	self.increment();	
});	
Bar
Reactive
• Foo emits events
• Bar subscribes
• Bar changes its state
A B
1 0 =A1 + A2
2 0 0
What’s Reactive programming?
A B
1 2 =A1 + A2
2 3 0
What’s Reactive programming?
A B
1 2 5
2 3 0
What’s Reactive programming?
Cycle.JS
Fully Reactive framework
RxJS as stream handlers
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Event<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
<li/>…<li/>
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
DOMDriver
main(DOM){
return fn(DOM);
}
Cycle.js data flow
Demo - Pizza topping selection
Demo light - Checkbox
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});


div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');


div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
let main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
const intent$ = DOM.select('input').events('change');
const model$ = intent$.map(ev => ev.target.checked)



div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

let main = ({DOM}) => {



















};
Cycle.run(main,	{	
	DOM:	makeDOMDriver('#app')	
});
.startWith(false);
const view$ = model$.map(toggled =>









return {DOM: view$};
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$
checked:	true,	
target:	input
Driver
Intent$
model$
view$
checked:	true,	
target:	input
Driver
Intent$
model$
view$
checked:	true,	
target:	input
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$
true
Driver
Intent$
model$
view$true
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$<input type=“checkbox” …>
Driver
Intent$
model$
view$
<input type=“checkbox” …>
Driver
Intent$
model$
view$
Driver
Intent$
model$
view$
Component
• Cycle app can be used as a component in a larger Cycle app
const main = ({DOM}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked)

.startWith(false);

const view$ = model$.map(toggled =>

div([

input({type: 'checkbox'}), 'Toggle me',

p(toggled ? 'ON' : 'off')

]));

return {DOM: view$};

};
const main = ({DOM}) => ({DOM:...});
const Toggle = ({DOM}) => ({DOM:...});
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

























};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});























};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});




















};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,



















};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);






};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);
return {

DOM: view$

}

};
DOM.select('input')const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);
return {

DOM: view$

}

};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM: DOM.select('.olives')});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

toggleOlives,

toggleMushrooms

])

);
return {

DOM: view$

}

};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM: DOM.select('.olives')});

const toggleMushrooms = Toggle({DOM});
const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
(toggleOlives, toggleMushrooms) =>

div([

div('.olives', [toggleOlives]),

toggleMushrooms

])

);
return {

DOM: view$

}

};
const Toggle = ({DOM}) => ({DOM:...});
const main = ({DOM}) => {

const toggleOlives = Toggle({DOM: DOM.select(‘.olives')});
const toggleMushrooms = Toggle({DOM: DOM.select('.mushrooms')});

const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,

(toggleOlives, toggleMushrooms) =>

div([

div('.olives', [toggleOlives]),

div('.mushrooms', [toggleMushrooms])

])

);

return {

DOM: view$

}

};
Component I/O
const props$ = $.of({

name: 'Pineapple'

})
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, }) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$,

(toggled, ) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, 

(toggled, ) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, ) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

props.name,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 



}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

props.name,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 

value$: model$
}

};
const props$ = $.of({

name: 'Pineapple'

})
const Toggle = ({DOM, props$}) => {

const intent$ = DOM.select('input').events('change');

const model$ = intent$.map(ev => ev.target.checked).startWith(false);

const view$ = $.combineLatest(model$, props$,

(toggled, props) =>

div([input({type: 'checkbox'}),

props.name,

p(toggled ? 'ON' : 'off')]));

return {

DOM: view$, 

value$: model$
}

};
const props$ = $.of({

name: 'Pineapple'

})
toggleOlives.value$.map(...)
Next
• More Drivers: HTTP, Storage, React Native
• HTML to hyperscript
• cyc - Generator
• awesome-cyclers: Lots of info
Questions?
Thank you!

More Related Content

Cyclejs introduction

  • 2. Who am I? Arye Lukashevski Software Engineer @ Wix.com
  • 4. What’s Reactive programming? Foo depends on Bar But who owns the relationship? Foo Bar
  • 5. Proactive • Foo invokes the action • Bar has an API for interaction • ‘Find usages’ Foo Bar Proactive Passive function onClick() { Bar.increment(); } Foo
  • 6. Foo Bar Listenable Reactive Foo.addSub('click', () => { self.increment(); }); Bar Reactive • Foo emits events • Bar subscribes • Bar changes its state
  • 7. A B 1 0 =A1 + A2 2 0 0 What’s Reactive programming?
  • 8. A B 1 2 =A1 + A2 2 3 0 What’s Reactive programming?
  • 9. A B 1 2 5 2 3 0 What’s Reactive programming?
  • 23. Demo - Pizza topping selection
  • 24. Demo light - Checkbox
  • 25. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 26. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 27. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 28. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 29. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') });
  • 30. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 31. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 32. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 33. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 34. let main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); const intent$ = DOM.select('input').events('change'); const model$ = intent$.map(ev => ev.target.checked)
 
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 let main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 }; Cycle.run(main, { DOM: makeDOMDriver('#app') }); .startWith(false); const view$ = model$.map(toggled =>
 
 
 
 
 return {DOM: view$};
  • 47. Component • Cycle app can be used as a component in a larger Cycle app
  • 48. const main = ({DOM}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked)
 .startWith(false);
 const view$ = model$.map(toggled =>
 div([
 input({type: 'checkbox'}), 'Toggle me',
 p(toggled ? 'ON' : 'off')
 ]));
 return {DOM: view$};
 };
  • 49. const main = ({DOM}) => ({DOM:...});
  • 50. const Toggle = ({DOM}) => ({DOM:...});
  • 51. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 
 
 
 
 
 
 
 
 
 
 
 
 };
  • 52. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 
 
 
 
 
 
 
 
 
 
 
 };
  • 53. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); 
 
 
 
 
 
 
 
 
 
 };
  • 54. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
 
 
 
 
 
 
 
 
 
 };
  • 55. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); 
 
 
 };
  • 56. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 57. DOM.select('input')const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 58. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM: DOM.select('.olives')});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 toggleOlives,
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 59. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM: DOM.select('.olives')});
 const toggleMushrooms = Toggle({DOM}); const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM, (toggleOlives, toggleMushrooms) =>
 div([
 div('.olives', [toggleOlives]),
 toggleMushrooms
 ])
 ); return {
 DOM: view$
 }
 };
  • 60. const Toggle = ({DOM}) => ({DOM:...}); const main = ({DOM}) => {
 const toggleOlives = Toggle({DOM: DOM.select(‘.olives')}); const toggleMushrooms = Toggle({DOM: DOM.select('.mushrooms')});
 const view$ = $.combineLatest(toggleOlives.DOM, toggleMushrooms.DOM,
 (toggleOlives, toggleMushrooms) =>
 div([
 div('.olives', [toggleOlives]),
 div('.mushrooms', [toggleMushrooms])
 ])
 );
 return {
 DOM: view$
 }
 };
  • 62. const props$ = $.of({
 name: 'Pineapple'
 })
  • 63. const props$ = $.of({
 name: 'Pineapple'
 })
  • 64. const Toggle = ({DOM, }) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$,
 (toggled, ) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 65. const Toggle = ({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, 
 (toggled, ) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 66. const Toggle = ({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, ) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 67. const Toggle = ({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 ,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 68. const Toggle = ({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 props.name,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 
 }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 69. const Toggle = ({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 props.name,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 value$: model$ }
 }; const props$ = $.of({
 name: 'Pineapple'
 })
  • 70. const Toggle = ({DOM, props$}) => {
 const intent$ = DOM.select('input').events('change');
 const model$ = intent$.map(ev => ev.target.checked).startWith(false);
 const view$ = $.combineLatest(model$, props$,
 (toggled, props) =>
 div([input({type: 'checkbox'}),
 props.name,
 p(toggled ? 'ON' : 'off')]));
 return {
 DOM: view$, 
 value$: model$ }
 }; const props$ = $.of({
 name: 'Pineapple'
 }) toggleOlives.value$.map(...)
  • 71. Next • More Drivers: HTTP, Storage, React Native • HTML to hyperscript • cyc - Generator • awesome-cyclers: Lots of info