Search code examples
javascriptreactive-programmingtogglebuttonrxjs

Create a toggle button with RxJS


I'm pretty new to the concept of Reactive Programming, and I'm just playing around a bit. To practice what I've learned I decided to write some code using RxJS in a real-world project and things are going great.

Now I want to create a simple toggle button:

let btn = $('button')[0]
let clicks = Rx.Observable.fromEvent(btn, 'click')
               .map(function(clickEvent) {
                  // decide to return true/false
               })

clicks.subscribe(value => {
    // value is true or false
})

I can't get my head around this very simple exercise without using DOM methods in my stream. In fact, I just need the latest value from the stream, and then invert it (!!value);

How can I implement this?


Solution

  • Does your button carry state only through the DOM? In that case it will be impossible to retrieve that state without querying the DOM.

    You could consider having your state out of the DOM and manipulate it without DOM functions. That said, you will have at some point to update the DOM state, but that you can do out of the stream in the observer.

    Something like this :

    var button_initial_state = false; // false for unchecked
    
    var button_state$ = Rx.Observable.fromEvent(btn, 'click')
                                     .scan (function(current_state, event){
                                        return !current_state;
                                      }, button_initial_state)
                                     .startWith(button_initial_state);
    
    button_state$.subscribe (function (state){
      // Code to set the button state in the DOM
    })
    

    Relevant documentation :