James Coccinella
James Coccinella

Reputation: 41

Use Polymer push method in a object

I'm a beginner to javascript and Polymer: i need to use native polymer push method in my custom object, but the browser it gives me back:

"Uncaught TypeError: Cannot read property 'length' of undefined"

This is a simplyfied version of my code:

<link rel='import' href='bower_components/polymer/polymer.html'>

<dom-module id='random-tag'>
  <template>
    <template is='dom-repeat' items='[[MyObject.getArray()]]'>
      <div>
        <h2>[[item.id]]</h2>
      </div>
    </template>
  </template>

  <script>
    Polymer({
      is: 'random-tag',

      properties: {
        MyObject: {
          type: Object
        }
      },

      MyObject2: function(){
        var myArray = [];
        var idMap = {};

        this.getArray = function(){
          return this.myArray
        };

        this.add = function(element){
          //The problem is here: probably Polymer don't see 'myArray'
          //in MyObject2 because the path is wrong
          Polymer.Base.push('myArray', element)
          idMap[element.id] = myArray.length
        };

        this.getIndex = function(id){
          return idMap[id]
        }
      },

      ready: function(){
        this.MyObject = new this.MyObject2()
        this.MyObject.add({id : 'thing1'})
        console.log('thing1 has index: ' + this.MyObject.getIndex('thing1'))
      }
    });
  </script>
</dom-module>

Upvotes: 3

Views: 869

Answers (2)

tony19
tony19

Reputation: 138326

The problem isn't a bad path, but rather that you're trying to use a Polymer.Base function inside MyObject2.

Assuming you don't need to define a separate class (i.e., MyObject2), a cleaner way to accomplish this is to define those properties/methods directly in the Polymer object (i.e., treat the Polymer object as your class encapsulation), like so:

<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>
      <h1>My Objects</h1>
      <template is='dom-repeat' items='[[myArray]]'>
        <div>
          <h2>[[item.id]]</h2>
        </div>
      </template>
    </template>
    <script>
      Polymer({
        is: 'x-foo',

        properties: {
          myArray: {
            type: Array,
            value: function() {
              return [];
            }
          },
          idMap: {
            type: Object,
            value: function() {
              return {};
            }
          }
        },

        add: function(element) {
          this.push('myArray', element);
          this.idMap[element.id] = this.myArray.length;
        },

        getIndex: function(id) {
          return this.idMap[id];
        },

        ready: function() {
          this.add({id: 'thing1'});
          this.add({id: 'thing2'});
          console.log('thing1 has index: ' + this.getIndex('thing1'));
        }
      });
    </script>
  </dom-module>
</body>

jsbin

Upvotes: 0

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657466

You need to start from a Polymer element like

<script>
    Polymer({
      is: 'random-tag',

      properties: {
        MyObject: {
          type: Object
        }
      },

      var self = this;

      MyObject2: function(){
        var myArray = [];
        var idMap = {};

        this.getArray = function(){
          return this.myArray
        };

        this.add = function(element){
          //The problem is here: probably Polymer don't see 'myArray'
          //in MyObject2 because the path is wrong
          self.push('myArray', element)
          idMap[element.id] = myArray.length
        };

        this.getIndex = function(id){
          return idMap[id]
        }
      },

      ready: function(){
        this.MyObject = new this.MyObject2()
        this.MyObject.add({id : 'thing1'})
        console.log('thing1 has index: ' + this.MyObject.getIndex('thing1'))
      }
    });
  </script>
</dom-module>

not tested (I don't know JS too well so use with caution)

Upvotes: 1

Related Questions