Search code examples
ajaxpolymerpolymer-2.xplunkeriron-elements

How to reset <iron-form> after dynamically loading data using <iron-ajax> in Polymer 2.x?


I want to reset my form buttons using the reset() method of the <iron-form>element.

Desired behavior

The desired behavior is that after clicking the Reset button, the two buttons that were originally unchecked to be unchecked and the two buttons that were originally checked to be checked.

Actual behavior

The actual behavior is that after clicking the Reset button, all the buttons flip to unchecked.

Demo

Here is my Plunker demo. Note that in reality I am loading data from Firebase. In the demo, I am loading it from myjson.com.

Steps to recreate the problem

  1. Open this demo.
  2. Notice two checked buttons and two unchecked.
  3. Check the two unchecked buttons.
  4. Click the Reset button.
  5. Notice all the buttons flip to unchecked.

The desired behavior is for the two buttons that were originally unchecked to be unchecked and the two buttons that were originally checked to be checked.

Code

https://plnkr.co/edit/viXDsAVrcmSOdAYriySm?p=preview
<base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
<link rel="import" href="polymer/polymer-element.html">
<link rel="import" href="paper-toggle-button/paper-toggle-button.html">
<link rel="import" href="iron-form/iron-form.html">
<link rel="import" href="iron-ajax/iron-ajax.html">
<link rel="import" href="paper-button/paper-button.html">


<dom-module id="my-demo">
  <template>
    <style>
      paper-button, form > * {
        margin-top: 40px;
        font-size: 18px;
      }
    </style>

    <iron-ajax
      id="ajax"
      auto
      url="https://api.myjson.com/bins/1dntup"
      last-response="{{item}}"
      handle-as="json"
      >
    </iron-ajax>

    <iron-form id="form">
      <form>
        <paper-toggle-button name="alice" checked="{{item.alice}}">Alice</paper-toggle-button>
        <paper-toggle-button name="bob" checked="{{item.bob}}">Bob</paper-toggle-button>
        <paper-toggle-button name="charlie" checked="{{item.charlie}}">Charlie</paper-toggle-button>
        <paper-toggle-button name="dave" checked="{{item.dave}}">Dave</paper-toggle-button>
      </form>
    </iron-form>

    <paper-button on-tap="_onTap">Reset</paper-button>

  </template>

  <script>
    class MyDemo extends Polymer.Element {
      static get is() {
        return 'my-demo';
      }
      static get properties() {
        return {
          item: {
            type: Object,
            notify: true,
          },
        };
      }

      ready() {
        super.ready();
      }

      _onTap() {
        this.$.form.reset();
        }

    }

    window.customElements.define(MyDemo.is, MyDemo);
  </script>
</dom-module>

Edits

User @madietov of the Polymer Slack Site points out that the source code here uses a protected method called _init() to initialize the default settings. And this _init() method seems to be called before the <iron-ajax> element returns its values.

_init() sets a protected property called _defaults. If I could access either the protected method or protected property, then I could call the method or set the property after <iron-ajax> returns its initial values.


Solution

  • Replace

    this.$.form.reset();
    

    with

    this.$.ajax.generateRequest();
    

    Demo

    https://plnkr.co/edit/4ROGJbzqk98X6FtbVSCN?p=preview
    <base href="https://polygit.org/polymer+v2.0.0/shadycss+webcomponents+1.0.0/components/">
    <link rel="import" href="polymer/polymer-element.html">
    <link rel="import" href="paper-toggle-button/paper-toggle-button.html">
    <link rel="import" href="iron-form/iron-form.html">
    <link rel="import" href="iron-ajax/iron-ajax.html">
    <link rel="import" href="paper-button/paper-button.html">
    
    
    <dom-module id="my-demo">
      <template>
        <style>
          paper-button, form > * {
            margin-top: 40px;
            font-size: 18px;
          }
        </style>
    
        <iron-ajax
          id="ajax"
          auto
          url="https://api.myjson.com/bins/1dntup"
          last-response="{{item}}"
          handle-as="json"
          >
        </iron-ajax>
    
        <iron-form id="form">
          <form>
            <paper-toggle-button name="alice" checked="{{item.alice}}">Alice</paper-toggle-button>
            <paper-toggle-button name="bob" checked="{{item.bob}}">Bob</paper-toggle-button>
            <paper-toggle-button name="charlie" checked="{{item.charlie}}">Charlie</paper-toggle-button>
            <paper-toggle-button name="dave" checked="{{item.dave}}">Dave</paper-toggle-button>
          </form>
        </iron-form>
    
        <paper-button on-tap="_onTap">Reset</paper-button>
    
      </template>
    
      <script>
        class MyDemo extends Polymer.Element {
          static get is() {
            return 'my-demo';
          }
          static get properties() {
            return {
              item: {
                type: Object,
                notify: true,
              },
            };
          }
    
          ready() {
            super.ready();
          }
    
          _onTap() {
            //this.$.form.reset();
            this.$.ajax.generateRequest();
            }
    
        }
    
        window.customElements.define(MyDemo.is, MyDemo);
      </script>
    </dom-module>
    
    Credit

    Summary from comments.
    Hat tip: @AneesHameed