Thursday, April 10, 2014

Where to Repeat in Polymer?


Up tonight, a closer look at repeating elements in Polymer. Specifically, I am trying to understand how the latest and, no doubt, greatest versions of the Dart and JavaScript versions of Polymer expect this to work.

Author's Note: This starts a series of posts that are much narrower in scope as I make a final push to get Patterns in Polymer ready by April 20, 2014.

As I have been working through a few Polymer.dart and JavaScript interoperation issues of late, I have noticed that the documentation for repeating elements seems to have changed. The documentation now would seem to suggest that repeating elements should now go inside <template> tags instead of placing a repeat attribute on the element being repeated.

In the past, I have repeated a list of ingredient options with the repeat attribute directly on the <option> elements being repeated:
        <option template repeat="{{ingredient in ingredients}}">
          {{ingredient}}
        </option>
The preferred way of doing this now would seem to be:
        <template repeat="{{ingredient in ingredients}}">
          <option>{{ingredient}}</option>
        </template>
I am going to try both with the most recent JavaScript and Dart. I start with a JavaScript project in which I have an unconstrained Bower dependency on Polymer:
{
  "name": "mdv_example",
  // ...
  "dependencies": {
    "polymer": "Polymer/polymer"
  }
}
A bower update installs Polymer 0.2.2, so I am ready to go.

And what I find is that the seeming recommended <template> format works:
        <template repeat="{{ingredient in ingredients}}">
          <option>{{ingredient}}</option>
        </template>
The template repeat options work as well:
        <option template repeat="{{ingredient in ingredients}}">
          {{ingredient}}
        </option>
But removing the template attribute from the latter does not work:
        <option repeat="{{ingredient in ingredients}}">
          {{ingredient}}
        </option>
This produces the following Polymer Expressions error:
Invalid expression syntax: ingredient in ingredients Error {stack: (...), message: "as and in can only be used within <template bind/repeat>"}
So the template attribute is a shorthand of sorts to convert any HTML element into a <template> wrapped version of the same element. That makes perfect sense and I probably even knew that at one point. Hopefully now I will remember.

When I try this in Dart, however, bad things happen. As in JavaScript, when there is no <template> and no template attribute, there is an error. Only in Dart the error message is not nearly as clear. Instead of being warned about an inappropriate repeat, I get an outright stack trace on attempting to use a non-existent variable (the named iterator variable):
Uncaught Error: Error evaluating expression 'ingredient': Class 'XPizzaToppings' has no instance getter 'ingredient'.

NoSuchMethodError: method not found: 'ingredient'
Receiver: Instance of 'XPizzaToppings'
Arguments: []
Even worse, I get the same error when I try to use the <template> approach in Dart. The only way to accomplish repeating elements is with the “shorthand” of the template attribute:
        <option template repeat="{{ingredient in ingredients}}">
          {{ingredient}}
        </option>
I am unsure of the significance in the documentation only using <template> binding. Is the shorthand being phased out in both projects, but so far only done in JavaScript? If the explicit <template> format worked in Dart, I might use it in Patterns in Polymer—it seems a little easier to read and more up front about what is happening in the code. Unfortunately, my need to be consistent between the two translations of the book and Dart's lack of <template> repeat support means that I will stick with the old attribute format. And possibly make a note of it in the JavaScript version of the book.


Day #30

2 comments:

  1. I would say they have just not caught up on that point with the Dart version. Though the unhelpful error in Dart is annoying

    ReplyDelete
  2. Yeah, it's clear to me that the preferred syntax uses the template element, but because of the way HTML table elements work, it is still required to use the template-as-an-attribute form of repeater on table rows.

    ReplyDelete