javascriptreactive-programmingfrpcyclejsxstream-js

Dropping button click events until last reset event not working


Using cycle.js and xstream, I would like to count button clicks and reset them.

I was planning to achieve this by counting all button clicks after the last reset. To do this I thought of dropping all button clicks until the last reset, and counting what's left.

However I'm left with 2 buttons that are not working

Any advice?

function main(sources: ISources): ISinks {
  const dom = sources.dom;
  const resetClick$ = dom.select("#resetButton")
    .events("click")
    .map(ev => 0)
    .startWith(0)

  const button1Click$ = dom.select("#button1")
    .events("click")
    .compose(dropUntil(resetClick$.last()))
    .map(ev => 1)
    .fold((acc, n) => acc + n, 0)
    .startWith(0)

  const button2Click$ = dom.select("#button2")
    .events("click")
    .compose(dropUntil(resetClick$.last()))
    .map(ev => 1)
    .fold((acc, n) => acc + n, 0)
    .startWith(0)

  const vtree$ = Stream.combine(button1Click$, button2Click$)
    .map(n =>
      div([
        input("#button1", { attrs: { type: "button", value: "Click Me!"}}),
        input("#button2", { attrs: { type: "button", value: "Click Me!"}}),
        input("#resetButton", { attrs: { type: "button", value: "Reset!"}}),
        p(["Clicks: " + n[0] + " + " + n[1]]),
        p(["Click total: " + (n[0] + n[1])])
      ])
    )

  const sinks: ISinks = {
    dom: vtree$
  };
  return sinks;
}

Solution

  • const resetClick$ = dom.select("#resetButton")
      .events("click")
      .map(ev => 0)
    
    const button1Click$ = dom.select("#button2")
        .events("click")
        .map(ev => 1)
    
    const button1WithReset$ = Stream.merge(button1Click, resetClick$)
      .fold((acc, n) => { 
          if (n == 0) return 0
          else return acc + n
      }, 0)
    

    This should do the trick. You can then do the same thing for button2Click.

    By merging button1click$ and resetClick$ we get a stream, that either emits 0 or 1. And using fold, we can reset the counter everytime our merged stream emits 0.