Polymer - Iterating over object in template

According to the polymer docs, an object or array can be iterated over using the repeat statement in a <template>:

"expression" can be a simple identifier, a path or a full expression (including Object and Array literals).

After testing, however, it seems as though the repeat statement only works with arrays, and not with objects:

http://jsbin.com/oqotUdE/4/edit

Am I doing something incorrectly?

Answers:

Answer

The docs there are imprecise. The general nature of expressions is explicated but I don't believe it intends to say you can iterate over objects with repeat.

I believe only Arrays are support for iteration at this time, although there is talk of possibly supporting NodeLists also.

Answer

I recently ran into this issue and got around it by using a filter which returns Object.keys(obj). Below is a simple example of how to do so (maybe there is a much better way, if so, enlighten me please)...

<template repeat="{{item in obj | getKeys}}">
  <span>Key: {{item}}</span>
  <span>Value: {{obj[item]}}</span>
</template>

...etc...

<script>
Polymer('my-element', {
  // yes i know, instantiate arrays/objects in the created method,
  // but this is just an example
  obj : {}, 

  // my custom filter function to use in looping objects
  getKeys : function(o){
    return Object.keys(o);
  }

});
</script>

Of course you can get more complex, checking for data types and making sure its an object. Below is a recursive version that loops through infinite nested objects (again, if there is a simpler way, let me know)

<template if="{{obj}}" id="root" bind="{{obj as o}}">

  <ul>

    <template repeat="{{item in o | getKeys}}">
      <li>

        <span class="key">{{item}}</span>

        <template if="{{o[item] | isNotObject}}">
          <span class="value">{{o[item]}}</span>
        </template>

        <template if="{{o[item] | isObject}}">
          <template ref="root" bind="{{o[item] as o}}"></template>
        </template>

      </li>
    </template>

  </ul>

</template>

...etc...

<script>
Polymer('object-view', {

  obj : {},

  getKeys : function(o){
    return Object.keys(o);
  },

  isObject : function(v){
    return typeof(v) === "object";
  },

  isNotObject : function(v){
    return typeof(v) !== "object";
  }

});
</script>

This certainly works (for me), to loop through objects (and arrays, actually). Although, I'm not completely happy with the use of Object.keys. I'll be very encouraged to see support for object iteration soon in polymer.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.