How can I execute javascript after the DOM is loaded in cycle.js? I can't put it in my main()
because the DOM is not loaded at that point. For context, I'm basically trying to initialize a fancy autocomplete which requires the target DOM element to exist, please feel free to give pointers if my approach is wrong.
I tried this:
sources.DOM.select(':root')
.observable.take(1)
.subscribe((element) => initAutoCompl())
...but select
was returning null
, I also tried selecting against other elements as well.
One way (using CycleJS with xstream) to execute JS code once after the DOM is ready is to run a (otherwise) non-operative observable. To do that select
':root'
then assign a non-existent event, and initiate the stream with startWith
. Once the stream is initiated run a map
that executes your setup function. To subscribe to the observable send it to a non-operative driver:
function main (sources) {
// Initiate observable, run setup function
const noop$ = sources.DOM.select(':root').events('noop')
.startWith(1).map(noop => runSetup())
...
return {
DOM: vdom$,
noop: noop$
}
}
...
Cycle.run(main, {
DOM: makeDOMDriver('#app'),
// non-operative driver
noop: noop$ => { noop$.addListener(
{next: noop => {}, error: ()=>{}, complete: ()=>{}}
) }
})
Another way is to run your setup script in a driver and trigger it with an of
observable.
function main (sources) {
// trigger observable
const setup$ = xs.of(1)
...
return {
DOM: vdom$,
setup: setup$
}
}
Cycle.run(main, {
DOM: makeDOMDriver('#app'),
// setup driver
setup: setup$ => { setup$.addListener({next: setup => {
// setup code goes here
console.log('run setup: ', document.querySelector('#app').children.length)
}, error: ()=>{}, complete: ()=>{}}) }
})
Codepen.io Setup Driver example.
If user input is needed before creating the DOM element:
function main (sources) {
const click$ = sources.DOM.select('div#clickme').events('click')
const vdom$ = click$
.mapTo(div('#newDomElement',"I'm new."))
.startWith(div('#clickme','Click me.'))
return {
DOM: vdom$,
setup: click$
}
}
Cycle.run(main, {
DOM: makeDOMDriver('#app'),
setup: setup$ => { setup$.addListener({next: setup => {
// setup code goes here
initAutoComplDummy()
}, error: ()=>{}, complete: ()=>{}}) }
})