1

In Javascript and using Kefir, I'd like to capture all key inputs until ENTER is hit. So far, I've managed to do this using bufferWhile like

var inputValues = Kefir
  .fromEvents(document.querySelector('body'), 'keydown')
  .bufferWhile(event => event.keyCode!=13);

var result = inputValues.toProperty(() => "");
result
.onValue(x => elm.innerHTML = x.slice(0,-1).map(y => String.fromCharCode(y.keyCode)).join(''))
.onError(() => elm.innerHTML = "?");

but initially I wanted to use a regular scan as in

var inputValues = Kefir
  .fromEvents(document.querySelector('body'), 'keydown')
  .scan((acc, y) => acc.concat(y), "");

but then how do I:

  1. Output the accumulator when ENTER is hit?
  2. Restart the accumulator to start a new keystroke sequence?

essentially, how do you compose bufferWhile using scan and a single stream? The answer doesn't have to be specifically about Kefir though, any FRP pseudo-code will do.

VH-NZZ
  • 5,248
  • 4
  • 31
  • 47
  • It works for you with `bufferWhile`, but you want to do the same with `scan`? – iofjuupasli Apr 27 '16 at 12:39
  • @iofjuupasli `scan` or anything else. I'd like to achieve the same and possibly add a timeout in order to capture clustered key strokes. – VH-NZZ Apr 27 '16 at 12:42

1 Answers1

1

I'm not sure this is what you want. In general, idea is to separate stream of confirmation and fulfilling. And combine it in some way:

const input$ = ...;
const key$ = input$.filter(isNotEnter).map(toChar);
const enter$ = input$.filter(isEnter);

const confirm$ = Kefir.merge([
    enter$,
    key$.debounce(1000)
]);

key$.bufferBy(confirm$);
VH-NZZ
  • 5,248
  • 4
  • 31
  • 47
iofjuupasli
  • 3,818
  • 1
  • 16
  • 17
  • Many thanks! Just took the liberty to adapt the first stream a little. What I was looking for was the `merge` and the `key$.bufferBy(confirm$)` parts. Why do you `debounce(1000)`? – VH-NZZ Apr 27 '16 at 13:05
  • `debounce` is just for example that you can confirm your input not only with enter, but also on any other event, like 1s after last input – iofjuupasli Apr 27 '16 at 13:10
  • Sorry for bugging you again but how would you specify that only strokes that occurred within 500 ms the `enter$` stream should be considered (assuming no `key$.debounce(1000)`)? – VH-NZZ Apr 27 '16 at 13:46
  • You mean only values between 500ms before enter, and enter time? – iofjuupasli Apr 27 '16 at 13:48
  • I think the most simple way would be to store time with each `input$` and then filter resulting array after `bufferBy`. But I'm not sure. Your question is pretty interesting, and I'm curious is there a better solution using only method on streams – iofjuupasli Apr 27 '16 at 13:55
  • Interesting. I'll look into it. Thanks anyway. – VH-NZZ Apr 27 '16 at 14:57