Why is this property of the polymer element resolved to undefined?

I am trying to dynamically assign an attribute to an iron-ajax pattern, 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> 

As a result, the URL looks like this:

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

The dom-module categoryid property is not undefined , since I can see the correct value of the property reflected in the attributes, which means that this is due to how to assign it to the attribute. I also tried this on created and attached callbacks and still didn't work.

Edit: categoryid is passed to the module when it is created as follows:

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

As you can see here, the categoryid passed to the service already matters. (The names of the elements in the image may differ slightly. I have abbreviated them to make the question less detailed.)

enter image description here

category-products-list where the service is called looks like

 <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> 
+7
javascript polymer web-component
source share
3 answers

I think that you are facing a combination of problems here, and you need to rethink your structure a bit.

First, since the categoryid attribute is bound outside of your element, its initial value will be undefined. Basically, your element is created and attached, and all life cycle methods are launched, and then the category is set. It also means that since you have iron-ajax installed with auto , it will first try to make a request with the information that it first gave.

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> 
+6
source share

the problem is how you pass categoryid to service products ... this is not a problem in the product service itself. If you run <products-service categoryid="5"></products-service> , this will work. Obviously, your application is much more complicated, but I created some simple elements that work correctly:

index.html

 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes"> <meta name="mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-capable" content="yes"> <title>My Test</title> <!-- Load platform support before any code that touches the DOM. --> <script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"> </script> <link rel="import" href="elements/product-list.html"> </head> <body> <product-list categoryid="5"></product-list> </body> </html> 

product-list.html:

 <link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="../elements/product-service.html"> <dom-module id="product-list"> <style> </style> <template> <product-service categoryid="{{categoryid}}"></product-service> </template> </dom-module> <script> Polymer({ is: 'product-list' }); </script> 

product-service.html:

 <link rel="import" href="../bower_components/polymer/polymer.html"> <link rel="import" href="../bower_components/iron-ajax/iron-ajax.html"> <dom-module id="product-service"> <style> </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> Polymer({ is: 'product-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() { console.log(this.categoryid); this.$.productsajax.params.id = this.categoryid; }, productsLoaded: function(e) { console.log('Response'); } }); </script> 
0
source share

Zikes diagnostics are correct, the reason undefined is returned is the lifetime of the page before the data is loaded onto the page. However, I could not get an answer to my decision. (Itโ€™s probably a mistake on my part somewhere.) My api also uses query strings to transfer data, while yours doesnโ€™t do this, I believe this answer will be useful for everyone who is faced with a situation like me . To solve this problem, I added an observer to my property, I based this answer on https://www.polymer-project.org/1.0/docs/devguide/observers . I used a simple observer. I find that Zikes uses sophisticated.

 <iron-ajax id="productsajax" url= {{ajaxUrl}} method='GET' on-response='productsLoaded' handleAs='json'> </iron-ajax> Polymer({ is: 'product-service', properties: { categoryid: { type: String, notify: true, reflectToAttribute: true, observer: 'catIdReady' }, ajaxUrl: { type: String, notify: true } }, catIdReady: function (catidnew, catidold) { this.set('ajaxUrl', this._getAjaxUrl()); this.$.productsajax.generateRequest(); console.log("catidReady!" + catidnew); }, _getAjaxUrl: function () { console.log(this.categoryid); return 'http://localhost:3003/api/taxons/products?categoryId=' + this.categoryid; }, 
0
source share

All Articles