Repeating Templates in Polymer

I ran into a little issue this afternoon working with templates in Polymer and I wanted to quickly jot down my thoughts in case others bump up against this.

Bindings

Bindings allow you to easily pipe some data into your markup from a JavaScript object of some kind. If you’ve worked with a library like Mustache or Handlebars before then they should feel familiar.

In Polymer land, the <template> tag has been extended so it supports a few handy binding attributes. These include bind, repeat, if, and ref.

How Not to Do It

If you take a look at the Polymer docs on template bindings you’ll notice that the binding attribute (bind, repeat, etc.) is always located on the first template. For instance:

<template repeat="{{ collection }}">
  Creates an instance with  for every element in the array collection.
</template>

This lead me to believe that I should write my element like this:

<polymer-element name="polymer-letters">
  <template repeat="{{ letter in letters }}">
    {{ letter }}
  </template>
  <script>
    Polymer('polymer-letters', {
      letters: ['a', 'b', 'c']
    });
  </script>
</polymer-element>

But unfortunately that does not work #sadtrombone.

The Right Way

Polymer uses the first template element to create Shadow DOM, so if you want to use a binding you’ll need to nest it inside another template.

Our updated example would look like this:

<polymer-element name="polymer-letters">
  <template>
    <template repeat="{{ letter in letters }}">
      {{ letter }}
    </template>
  </template>
  <script>
    Polymer('polymer-letters', {
      letters: ['a', 'b', 'c']
    });
  </script>
</polymer-element>

And here it is running on CodePen:

See the Pen Polymer Template Bindings by Rob Dodson (@robdodson) on CodePen

I mentioned this to Eric Bidelman and he opened a ticket to improve the docs, so keep an eye out for that. Hope this helps some of you that may have been stuck :)