Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this polymer element's property resolve to undefined?

I am trying to dynamically assign an attribute to an iron-ajax template but it resolves to undefined.

<dom-module id="products-service">
  <style>
    :host {
      display: none;
    }
  </style>

  <template>
    <iron-ajax id="productsajax"
      auto
      url="http://localhost:3003/api/taxons/products"
      params='{"token":"my-token"}'
      method='GET'
      on-response='productsLoaded'
      handleAs='json'>
    </iron-ajax>
  </template>
</dom-module>

<script>
(function() {
    Polymer({
        is: 'products-service',

        properties: {
            categoryid: {
                type: String,
                notify: true,
                reflectToAttribute: true
            }
        },

        //here I am trying to add and `id` to the `iron-ajax` `params` attribute.
        ready: function() {
            this.$.productsajax.params.id = this.categoryid;
       }
    });
})();
</script>

The resulting url looks like this:

`http://localhost:3003/api/taxons/products?token=my-token&id=undefined`

The dom-module's categoryid property is not undefined as i can see the correct property value reflected on the attributes which means it something to do with how am assigning it to the attribute. I have also tried this on the created and attached callbacks and still not working.

Edit: The categoryid is passed to the module when instantiating it like this:

<products-service products="{{products}}" categoryid="{{categoryid}}"></products-service>

As seen here the categoryid passed to the service already has a value. (the element names on the image may be slightly different. I shortened them to make the question less verbose.)

enter image description here

The category-products-list where the service is being called looks like this

<dom-module id="category-products-list">
  <template>
    <category-products-service products="{{products}}" categoryid="{{categoryid}}"></category-products-service>
    <div>
      <template is="dom-repeat" items="{{products}}">
       <product-card on-cart-tap="handleCart" product="{{item}}">
         <img width="100" height="100">
         <h3>{{item.name}}</h3>
         <h4>{{item.display_price}}</h4>
       </product-card>
     </template>
  </div>
</template>

</dom-module>

<script>
 (function() {
  Polymer({
  is: 'category-products-list',

  properties: {
    categoryid: {
      type: String,
      notify: true,
      reflectToAttribute: true
    }
  },

ready: function() {
   //this is undefined too
   console.log("categoryid in the list module: "+categoryid)
   }
   });
   })();
</script>
like image 566
Optimus Pette Avatar asked Jun 09 '15 19:06

Optimus Pette


1 Answers

I think you're running into a combination of issues here, and need to slightly rethink your structure.

First, because the categoryid attribute is bound outside of your element its initial value will be undefined. Basically, your element is created and attached, with all lifecycle methods run, and then categoryid gets set. This also means that because you have an iron-ajax with auto set, it will initially try to make a request with the information it is first given.

My recommended changes:

<dom-module id="products-service">
  <style>
    :host {
      display: none;
    }
  </style>

  <template>
    <iron-ajax id="productsajax"
      url="http://localhost:3003/api/taxons/products"
      params='{"token":"my-token"}'
      method='GET'
      on-response='productsLoaded'
      handleAs='json'>
    </iron-ajax>
  </template>
</dom-module>

<script>
(function() {
    Polymer({
        is: 'products-service',

        properties: {
            categoryid: {
                type: String,
                notify: true,
                reflectToAttribute: true
            }
        },

        observers: [
            // Note that this function  will not fire until *all* parameters
            // given have been set to something other than `undefined`
            'attributesReady(categoryid)'
        ],

        attributesReady: function(categoryid) {
            this.$.productsajax.params.id = categoryid;

            // With the removal of `auto` we must initiate the request
            // declaratively, but now we can be assured that all necessary
            // parameters have been set first.
            this.$.productsajax.generateRequest();
        }
    });
})();
</script>
like image 55
Zikes Avatar answered Oct 14 '22 22:10

Zikes