Krimo
Krimo

Reputation: 954

Access nested array in Polymer repeat

I have a users array like so :

        [{
            "name": "John",
            "surname": "McClane",
            "prefs": [{
                "Gourmande": 1,
                "Espiegle": 0
            }]
        },
        {
            "name": "Robert",
            "surname": "DeNiro",
            "prefs": [{
                "Gourmande": 1,
                "Espiegle": 0
            }]
        },
        {
            "name": "Siegfried",
            "surname": "Klause",
            "prefs": [{
                "Gourmande": 1,
                "Espiegle": 0
            }]
        }]

Which I access in my template like so :

<ul class="userlist">
    <template repeat="{{ user in users }}">
        <li class="user">
            {{user.name}} preferences are listed below : <br>
            <template repeat="{{ pref in user.prefs }}">
                - {{ pref }} <br>
                <!-- {{ pref.Gourmande }} works fine, but I want to display "Gourmande" -->
            </template>
        </li>
    </template>
</ul>

I am unable to iterate over the prefs. I've tried the above configuration, nesting template tags, using array-like notation (user.prefs[0], user.prefs.slice(0)), all to no avail.

Can anybody point me in the right direction? What I'd like to do is ultimately to be able to list the key/value pairs of the prefs array (because its name/size will be changing constantly).

Thank you.

EDIT : I found the solution thanks to the filter you guys suggested :

    <template repeat="{{ pref in users.prefs }}">
        <template repeat="{{k in pref | keys}}">
            <li class="pref">
                {{ k }} : {{ pref[k] }}
            </li>
        </template>
    </template>

And the filter used is the one in Scott's answer.

Upvotes: 2

Views: 2634

Answers (4)

nikolayp
nikolayp

Reputation: 17949

I used a array in array for the purpose, like this:

<polymer-element people="[[1, "Brad B"], [2, "Alis A"], [3, "Samon S"]]">
</polymer-element>

<polymer-select value="{{ person }}">
  <option repeat="{{person in people}}" template value="{{person[0]}}">{{person[1]}}
  </option>
</polymer-select>

enter image description here

Upvotes: 0

Scott Miles
Scott Miles

Reputation: 11027

You cannot use template repeat over an Object, only over an Array.

You can get close to the syntax you want like so:

<template repeat="{{key in object | keys}}">
  {{key}}: {{object[key]}}<br>
</template>

where keys is a filter on your prototype:

keys: function(object) {
  return Object.keys(object);
}

http://jsbin.com/ciduhe/3/edit

Upvotes: 4

Peter Burns
Peter Burns

Reputation: 45361

You can write your own filter to give you an object's keys and use that to repeat over your object.

For example:

<polymer-element name='my-elem'>
  <template>
    <ul>
    <template repeat="{{key in obj | objectKeys}}">
      <li>{{key}} - {{obj[key]}}</li>
    </template>
    </ul>
  </template>
  <script>
    Polymer('my-elem', {
      obj: {a: 1, b: 2, c: 3},
      objectKeys: function(inp) {
        var keys = Object.keys(inp);
        // important, as Object.keys may come in arbitrary order
        keys.sort(); 
        return keys;
      }
    });
  </script>
</polymer-element>

Try it out with this jsbin: http://jsbin.com/hozahupa/1/edit

Upvotes: 1

Dirk Grappendorf
Dirk Grappendorf

Reputation: 3422

I found this commit of a project where they use a filter function to convert the object values into an array

src/juicy-tree.html

This results in nice template expression (<template repeat="{{ user.prefs | objectValues as pref }}">), but the problem with this is that there is no data binding with the prefs property of the original user object.

This might be ok if you only need a one time binding.

Upvotes: 1

Related Questions