Search code examples
javascriptcyclejsxstream-js

Cyclejs and xstream not displaying anything


I m trying to create a stream from an array logging inside of its map operator but it seems that something goes wrong in my code and I can't point it out...

import {Slider} from './slider/slider'
import xs from 'xstream'

export function App(sources) {
    const props = {
        marbles$: xs.fromArray([{
            color: 'red',
            x: 0
        }, {
            color: 'blue',
            x: 20
        }])
    }

    props.marbles$.map(item => {
        console.log(item) // nothing displayed on here
        return item
    })
    return Slider(Object.assign(sources, {props}))
}

On this little code, I m simply creating a props object containing a marbles$ stream from an array.

Just below I try to log on each item in the stream but nothing happens, and I don't understand why.


Plunker here : https://plnkr.co/edit/6uMsLIl1Edd5x670OqHa?p=preview

Nothing to show on the HTML file, only on the JS file

Any idea ?


Solution

  • As stated in the xstream docs, streams are idle (not executed) until they get their first listener, which is accomplished with the addListener method.

    Notice below that the props.marbles$.map stream is assigned to variable y. Then the y.addListener method is invoked. When addListener is called, the props.marbles$.map method is finally executed.

    const props = {
      marbles$: xstream.Stream.fromArray([{
        color: 'red',
        x: 0
      }, {
        color: 'blue',
        x: 20
      }])
    }
    
    const y = props.marbles$.map(item => {
        console.log('map', item)
        return item
    })
    
    y.addListener({})
    

    Outputs in the console:

    map > Object {color: "red", x: 0}
    map > Object {color: "blue", x: 20}
    

    Alternatively you can put the console.log in the next property of the listener instead of the map method:

    const y = props.marbles$.map(item => {
      return item
    })
    
    y.addListener({
      next: item => console.log('listener', item)
    })
    

    Outputs in the console:

    listener > Object {color: "red", x: 0}
    listener > Object {color: "blue", x: 20}
    

    OR, as André suggested, you can use xstream debug:

    const props = {
      marbles$: xstream.Stream.fromArray([{
        color: 'red',
        x: 0
      }, {
        color: 'blue',
        x: 20
      }]).debug('debug 1')
    }
    
    const y = props.marbles$.map(item => {
      return item
    }).debug('debug 2')
    
    y.addListener({})
    

    Outputs in the console:

    debug 1 > Object {color: "red", x: 0}
    debug 2 > Object {color: "red", x: 0}
    debug 1 > Object {color: "blue", x: 20}
    debug 2 > Object {color: "blue", x: 20}