Cycle.js FAQ

Some Cycle.js FAQ notes I threw together and will try rearrange that might help people using Cycle.js. Some of these are notes copied from the Cycle.js Gitter channel.

Why does Cycle.js code often have $ symbols in variables

The $ convention is used to signify a variable that is an Observable.

Another not so standard idea is to import Observable as another name like $, eg

1
import { Observable as $ } from 'rx';

Debugging Cycle.js

  • How to debug RxJS code
  • Adding a debugger; line to your code can be useful to break into your browser debug mode.
  • Logging RxJS (see below)

Logging for RxJS

1
2
3
var foo$ = bar$
.map(……..)
.do(x => console.log('foo$ emits ' + x));

or a prototype from @milankinen's gist

1
2
3
4
5
Rx.Observable.prototype.log = function(prefix) {
return process.env.NODE_ENV !== "development" ? this : this
.doOnCompleted(() => console.log(prefix, "<completed>")) // eslint-disable-line
.do(x => console.log(prefix, x)) // eslint-disable-line
}

Cycle.js Templating System

Cycle.js recommends using HyperScript Helpers, which I also prefer. There is also plain HyperScript and the React JSX support.

HyperScript and HyperScript Helpers

Hyperscript plain and Hyperscript helper conversion from HTML http://html-to-hyperscript.paqmind.com/

State

Redux concept in RxJS:

1
2
3
4
5
function store(action$) {
return makeReducerStream(action$)
.scan((state, reducer) => reducer(state), initialState)
.shareReplay(1);
}

What is Transposition in Cycle.js

@staltz Transposition is: a child of a vdom element can be an Observable<VElement> and at the end it will be flattened as one "video".

Combinators in this article are the same concept.

Isolate, Children and Events

A really cool example by @laszlokorte on how events and isolation work with surrounding discussion on the TSERS Gitter channel.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function Foo() {
return {
DOM: O.just(h("button.foo", "..."))
}
}
function Bar(sources) {
const click$ = DOM.select(".foo").events("click")
const click2$ = DOM.select(".bar").events("click")
const foo = isolate(Foo, "f1")(sources)
const vdom$ = foo.DOM.map((foo) => div('.bar',[
foo,
]))
return {
DOM: vdom$
}
}

click2$ will see the event that happens when the user clicks button.foo

Input Forms in Cycle.js

Here are some example repos with ideas on how to make input forms:

How go listen for keypress events on the whole app

Normally you listen to global keypresses with a driver as @TylorS explains here:

1
2
3
Cycle.run(main, {
keypress$: () => Rx.Observable.fromEvent(document, 'keypress')
})

The reason DOM.select() doesn't select from document, is because it's external to your main(). Drivers are the place where you listen to what is external to your main().