Macks Macks - 1 year ago 126
Javascript Question

Creating a filterable list with RxJS

I'm trying to get into reactive programming. I use array-functions like map, filter and reduce all the time and love that I can do array manipulation without creating state.

As an exercise, I'm trying to create a filterable list with RxJS without introducing state variables. In the end it should work similar to this:

enter image description here
enter image description here

I would know how to accomplish this with naive JavaScript or AngularJS/ReactJS but I'm trying to do this with nothing but RxJS and without creating state variables:

var list = [

Rx.Observable.fromEvent(document.querySelector('#filter'), 'keyup')
.map(function(e) { return; });

// i need to get the search value in here somehow:
Rx.Observable.from(list).filter(function() {});

Now how do I get the search value into my filter function on the observable that I created from my list?

Thanks a lot for your help!


You'll need to wrap the from(list) as it will need to restart the list observable again every time the filter is changed. Since that could happen a lot, you'll also probably want to prevent filtering when the filter is too short, or if there is another key stroke within a small time frame.

//This is a cold observable we'll go ahead and make this here
var reactiveList = Rx.Observable.from(list);

//This will actually perform our filtering
function filterList(filterValue) {
  return reactiveList.filter(function(e) {
   return /*do filtering with filterValue*/;

var source = Rx.Observable.fromEvent(document.querySelector('#filter'), 'keyup')
  .map(function(e) { return;})

  //The next two operators are primarily to stop us from filtering before 
  //the user is done typing or if the input is too small
  .filter(function(value) { return value.length > 2; })
  .debounce(750 /*ms*/)

  //Cancel inflight operations if a new item comes in.
  //Then flatten everything into one sequence

//Nothing will happen until you've subscribed
source.subscribe(function() {/*Do something with that list*/});

This is all adapted from one of the standard examples for RxJS here