I am trying to capture hover events on a list of items between the first and second clicks of any of items in the list.
E.g.
- User clicks item in list
- Hover stream items emits event
- User performs second click in list and hover events stop
I have setup an observable stream as follows:
let items = document.getElementsByClassName("item");
let itemClicks = Rx.Observable.fromEvent(items, "click");
let itemHover = Rx.Observable.fromEvent(items, "mouseenter");
let clicksWithFlag = itemClicks.scan((acc, val) => ({ val: val.target.innerHTML, firstClick: !acc.firstClick}), {});
//create stream of 1st clicks
let firstClicks = clicksWithFlag.filter(x => x.firstClick).pluck('val');
//create stream of second clicks
let secondClicks = clicksWithFlag.filter(x => !x.firstClick).pluck('val');
let hoverBetweenFirstAndSecondClick = firstClicks.flatMap(x => itemHover.takeUntil(secondClicks));
The problem I am running into is the itemHover.takeUntil(secondClicks)
doesn't end the itemHover stream. I think it's related to firstClicks and secondClicks stemming from the same observable, but can't figure it out.
It works if I swap the takeUntil(secondClicks) for any other stream (e.g. a stop button).
See this JSBin for an example: https://jsbin.com/dotapis/edit?js,console,output
Hope somebody can help. I am trying to build a range selector using RxJS, but am starting to think that splitting the stream into first and second clicks may not be the best route.
Update
Just tried this with BaconJS and I can get it working with pretty much the exact same code. https://jsbin.com/fobumu/edit?js,console,output
I'm convinced the problem lies in non-idiomatic use of streams, but not sure why.