RxJS and React multiple clicked elements to form single data array RxJS and React multiple clicked elements to form single data array arrays arrays

RxJS and React multiple clicked elements to form single data array


Make your filter items an Observable streams of click events using Rx.Observable.fromevent (see https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/events.md#converting-a-dom-event-to-a-rxjs-observable-sequence) - it understands a multi-element selector for the click handling.

You want to keep receiving click events until a debounce has been hit (user has enabled/disabled all filters she wants to use). You can use the Buffer operator for this with a closingSelector which needs to emit a value when to close the buffer and emit the buffered values.

But leaves the issue how to know the current actual state.

UPDATE

It seems to be far easier to use the .scan operator to create your filterState array and debounce these.

const sources = document.querySelectorAll('input[type=checkbox]');const clicksStream = Rx.Observable.fromEvent(sources, 'click')  .map(evt => ({        name:  evt.target.name,        enabled: evt.target.checked  }));const filterStatesStream = clicksStream.scan((acc, curr) => {  acc[curr.name] = curr.enabled;  return acc}, {}).debounce(5 * 1000)filterStatesStream.subscribe(currentFilterState => console.log('time to do something with the current filter state: ', currentFilterState);

(https://jsfiddle.net/crunchie84/n1x06016/6/)


Actually, your problem is about RxJS, not React itself. So it is easy. Suppose you have two function:

const removeTag = tagName =>  tags => {    const index = tags.indexOf(index)    if (index !== -1)      return tags    else      return tags.splice(index, 1, 0)  }const addTag = tagName =>  tags => {    const index = tags.indexOf(index)    if (index !== -1)      return tags.push(tagName)    else      return tags  }

Then you can either using scan:

const modifyTags$ = new Subject()modifyTags$.pipe(  scan((tags, action) => action(tags), [])).subscribe(tags => sendRequest(tags))modifyTags$.next(addTag('a'))modifyTags$.next(addTag('b'))modifyTags$.next(removeTag('a'))

Or having a separate object for tags:

const tags$ = new BehaviorSubject([])const modifyTags$ = new Subject()tags$.pipe(  switchMap(    tags => modifyTags$.pipe(      map(action => action(tags))    )  )).subscribe(tags$)tags$.subscribe(tags => sendRequest(tags))