1

I have a firebase structure like this:

  "workouts" : {
    "-KBJiXAHZV2B8sj9-FNk" : {
      "exercise_templates" : {
        "-KEsVT-ukSHMNevLFCa1" : true,
        "-KEslP747OVTdIYrNmCv" : true,
        "-KEslUBaSsmTOiVgV_h_" : true,
        "-KFpJyXrZwY_aPiDGGvw" : true
      },
      "name" : "ICF A"
    }
  }

  "exercise_templates" : {
    "-KEsVT-ukSHMNevLFCa1" : {
      "name" : "Overhead Press",
      "reps" : "5",
      "sets" : "5",
      "workouts" : {
        "-KBJiXAHZV2B8sj9-FNk" : true,
        "-KEsU4Q0irvgh33I20JF" : true
      }
    },

I'm trying to loop through all exercise_templates that belong to a workout:

            <template is="dom-repeat" items="[[workouts]]" as="workout">
              <paper-card heading="[[workout.name]]">
                <div class="card-content">
                  [[workout.__firebaseKey__]]

                  <template is="dom-repeat" items="[[workout.exercise_templates]]" as="template" handle-as="json">
                    {{template}}
                  </template>

                </div>
                <div class="card-actions">
                  <paper-button>Some action</paper-button>
                </div>
              </paper-card>
            </template>

But I get:

[dom-repeat::dom-repeat]: expected array for `items`, found Object {-KEsVT-ukSHMNevLFCa1: true, -KEslP747OVTdIYrNmCv: true, -KEslUBaSsmTOiVgV_h_: true, -KFpJyXrZwY_aPiDGGvw: true}

How would I go about referencing an exercise_template by iterating through the exercise_templates in workouts?

Custom element

<dom-module id="my-workout">
  <template>
    <template is="dom-bind">
      <style>
        :host {
          display: block;
        }

        span {
          @apply(--paper-font-body1);
        }
      </style>
      <firebase-collection
        limit-to-first="10"
        location="https://blazing-inferno-5257.firebaseio.com/workouts"
        data="{{workouts}}" keys="{{keys}}"></firebase-collection>
      <template is="dom-repeat" items="[[workouts]]" as="workout">
        <paper-card heading="[[workout.name]]">
          <div class="card-content">
            <template is="dom-repeat" items="[[_computeExerciseTemplates(workout)]]">
              <li>{{item}}</li>
            </template>
          </div>
          <div class="card-actions">
            <paper-button>Do workout</paper-button>
          </div>
        </paper-card>
      </template>
    </template>
  </template>

  <script>
    (function() {
      'use strict';

      Polymer({
        is: 'my-workout',
        _computeExerciseTemplates: function(workout) {
          return Object.keys(workout.exercise_templates);
        },

        ready: function() {
        }
      });
    })();
  </script>
</dom-module>
amunds
  • 702
  • 8
  • 22
  • You can found the solution here: http://stackoverflow.com/questions/30781500/how-to-use-dom-repeat-with-objects-instead-of-arrays-in-polymer-1-0/30794220#30794220 – Nel Gonzalez Sep 11 '16 at 16:05

1 Answers1

0

Assuming exercise_templates cannot be changed into a simple array (or that it's undesirable), you could use a computed binding for exercise_templates to get its keys:

<template is="dom-repeat" items="[[_computeExerciseTemplates(workout)]]">
  <li>{{item}}</li>
</template>

where _computeExerciseTemplates is defined as:

<script>
  Polymer({
    ...
    _computeExerciseTemplates: function(workout) {
      return Object.keys(workout.exercise_templates);
    }
  });
</script>

<head>
  <base href="https://polygit.org/polymer+:master/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
</head>

<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <template is="dom-repeat" items="[[workouts]]" as="workout">
        <h2>{{workout.name}}</h2>
        <ul>
          <template is="dom-repeat" items="[[_computeExerciseTemplates(workout)]]">
            <li>{{item}}</li>
          </template>
        </ul>
      </template>
    </template>

    <script>
      Polymer({
        is: 'x-foo',

        properties: {
          workouts: {
            type: Array,
            value: function() {
              return [{
                //"-KBJiXAHZV2B8sj9-FNk" : {
                "exercise_templates": {
                  "-KEsVT-ukSHMNevLFCa1": true,
                  "-KEslP747OVTdIYrNmCv": true,
                  "-KEslUBaSsmTOiVgV_h_": true,
                  "-KFpJyXrZwY_aPiDGGvw": true
                },
                "name": "ICF A"
                  //}
              }]
            }
          }
        },
        _computeExerciseTemplates: function(workout) {
          return Object.keys(workout.exercise_templates);
        }
      });
    </script>
  </dom-module>

</body>

jsbin

  • For some reason I'm getting [dom-bind::_annotatedComputationEffect]: compute method `_computeExerciseTemplates` not defined even though I've put _computeExerciseTemplates under Polymer({}) in my custom element. – amunds Apr 28 '16 at 20:18
  • I've added my entire custom element to the question. – amunds Apr 28 '16 at 20:36
  • I wouldn't mind if workout.exercise_templates could be made into a simple array, all I need is the key from each workout.exercise_template as a string. – amunds Apr 28 '16 at 20:48
  • Your `` definition has an unnecessary ` –  Apr 28 '16 at 21:04
  • If you change `workout.exercise_templates` into a simple string array, your original code should work (and you wouldn't need a computed binding). –  Apr 28 '16 at 21:07
  • Sorry for not getting this, but how can I access – amunds Apr 28 '16 at 21:31
  • You would use `this.workouts` (note the trailing `s`). I'd be happy to go into detail if you post a new question about it. –  Apr 28 '16 at 21:50