Search code examples
ecmascript-6reduxmaterial-designpolymer-2.x

How to build a Redux reducer for a paper-toggle-button in Polymer 2?


I have not found an example/demo or documentation on the proper way to process an "on-change" or "on-click" user action from a paper-toggle-button, for Redux.

Right now, I have an annotated event listener function that gets invoked, but in that function, I cannot seem to get a reference back to the source element. I need the new on/off value and the id attribute value so I can update the correct state in the Redux store. I have several paper-toggle-button elements in the view, each for a different property in the Redux store.

I added an event listener for "checked-changed", but the thrown event did not include a reference back to the html element. Why would the event not say where it came from?

"event.target" points to the outer container which is holding the child elements that throw the event. To learn this, I set a breakpoint on console.log(event.target.nodeName).

I suppose I could query select all the toggle elements and save all the values to the Redux store but I'd rather only update the one that changed.

The documentation suggests that I should be able to use "this" as a reference to the outer custom element holding my paper-toggle-button elements, which seems useless because I need the id to query for the element that threw the event.

It is important to note that I'm building my paper-toggle-button elements with dom-repeat. I am iterating through a small array of objects to build a few toggles. That means that all toggles will call the same event handler function for the on-change event. I have to do that because the toggles can be reordered manually with drag and drop, which requires dom-repeat, unfortunately. If drag-n-drop was not a requirement, I could ditch the dom-repeat and just build a static/fixed list of toggles, where each toggle would have its own event handler.

As you might have guessed, I'm new to front end development.


Solution

  • Have you watched Rob Dodson's Polycasts #61 and #62? They use Polymer 1, but I've posted Polymer 2 versions on GitHub at https://github.com/johnthad/polycast61 and https://github.com/johnthad/polycast62

    I'm new to Polymer and Redux but so far have been successful. I think this will work:

    In redux-store.html:

    const initialState = {
      toggled: false,
      ...
    };
    
    const reducer = (state = initialState, action) => {
      switch (action.type) {
        case 'TOGGLED':
          return Object.assign({}, state, {
            toggled: action.toggled;
          });
      ...
    

    In my-element.html:

    <paper-toggle-button 
      id="foo" on-tap="_doTap">Toggle</paper-toggle-button>
    
    ...
    
    static get properties() {
      return {
        toggled: {
          type: Boolean,
          statePath: 'toggled'
        },
      ...
    }
    
    static get actions() {
      return {
        toggled() {
          return {
            type: 'TOGGLED'
          };
        }
      }
    }
    
    _doTap(e) {
      this.dispatch('toggle', this.$.foo.checked);
    //  this.$.foo.checked = this.toggled;  // <- not needed
    }