Search code examples
javascriptpolymerpolymer-2.x

Passing an object to element attribute in Polymer 2


I am playing with Polymer 2.0, and I don't understand how to pass an object as an element attribute.

Here's my code:

<dom-module id="notes-app">
  <template>
    <style>
      :host {
        display: block;
      }
    </style>
  <button on-click="loadNotes">Get the notes</button>
  <template is="dom-repeat" items="[[notes]]" as="note">
     <note recipe='JSON.stringify(note)'></note>
  </template>
</template>
<script>
  class NotesApp extends Polymer.Element {
    static get is() { return 'notes-app'; }
    static get properties() {
      return {
        notes: {
          type: Array,
          value: []
        }
      };
    }
    loadNotes() {
      this.notes = [
        {"desc":"desc1", "author":"auth1", "type":"type1"},
        {"desc":"desc2", "author":"auth2", "type":"type2"},
        {"desc":"desc3", "author":"auth3", "type":"type3"}
      ];
    }
  }
  window.customElements.define(NotesApp.is, NotesApp);
</script>
</dom-module>

simple-note is the element who has a property of type Object:

<dom-module id="note">
  <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <div>
      <fieldset>
        <label>description</label>{{note.desc}}<br>
        <label>author</label>{{note.author}}<br>
        <label>type</label>{{note.type}}
      </fieldset>
    </div>
  </template>
  <script>
    class SimpleNote extends Polymer.Element {
      static get is() { return 'simple-note' }
      static get properties() {
        return {
          note: {
            type: Object,
            value:  {},
            notify: true
          }
        };
      }
    }
    customElements.define(SimpleNote.is, SimpleNote);
  </script>
</dom-module>

As you can see I want note-app to display all the objects in its notes property by passing an object representing a note to every simple-note elements (don't known if it is the right way to make elements interact each other). I want it to happen when I press the notes-app button. How can I pass an object to an element attribute in this case?


Solution

  • Since you're trying to pass the variable as an object, you should use property bindings instead of attribute bindings (which only supports strings).

    • Polymer data bindings require curly or square brackets ({{twoWayBinding}} or [[oneWayBinding]]). For example, to set the foo property of the <x-child> element to the value of note, the template would look something like this:

      <template is="dom-repeat" items="[[notes]]" as="note">
        <x-child foo="[[note]]">
      </template>
      
    • Given that SimpleNote.is equals "simple-note", I assume your usage of <note> and <dom-module id="note"> were only typos in your question. They should be set to simple-note, as the element name must start with a lowercase ASCII letter and must contain a dash.

    • It looks like you're binding a recipe property, but <simple-note> declares a note property (and no recipe) and binds to note sub-properties in its template. I assume recipe is another typo.

    working demo