I know a little bit of BaconJS, but now I'm trying to learn RxJS by creating a "User is typing..." indicator. It's pretty simple, it can be explained in two simple rules:
I'm not sure if this is correct, but I have so far created two streams:
0
every second.1
for every event.Then I merge them together, and simply tap into the result. If it's a 1
, then I show the indicator. If it's a 0
, then I hide the indicator.
This is what that looks like:
const showTyping = () =>
$('.typing').text('User is typing...');
const showIdle = () =>
$('.typing').text('');
// 1 second heartbeats are mapped to 0
const heartbeat$ = Rx.Observable
.interval(1000)
.mapTo(0);
// user typing events are mapped to 1
const input$ = Rx.Observable
.fromEvent($('#input'), 'input')
.mapTo(1);
// we merge the streams together
const state$ = heartbeat$
.merge(input$)
.do(val => val === 0 ? showIdle() : showTyping())
.subscribe(console.log);
Here is a link to the JSBin:
http://jsbin.com/vekixuv/edit?js,console,output
There are several problems and questions I have with this implementation:
0
sneaks through, so the indicator flashes away for a split second before coming back on the next user keystroke.I have a feeling that I am completely off-base with my implementation, I appreciate any help that you may be able to provide. Thanks.
You don't even need to use two Observables and use just one with debounceTime()
. All the logic you tried to make is already present in debounceTime()
operator:
const showTyping = () =>
$('.typing').text('User is typing...');
const showIdle = () =>
$('.typing').text('');
const input$ = Rx.Observable
.fromEvent($('#input'), 'input')
.do(() => showTyping())
.debounceTime(1000)
.subscribe(() => showIdle());
See live demo: http://jsbin.com/cixipa/6/edit?js,console,output