Optimus Pette Optimus Pette - 5 months ago 172
Javascript Question

Show Polymer indeterminate paper-progress when iron-ajax is loading

I am trying to show a paper-progress when an

iron-ajax
request is in progress with no success. Below is the code for a custom element
get-products-service
which hosts the
iron-ajax
request, and a
products-list
which hosts the
paper-progress
.

This is the whole
products-list
dom-module
:

<dom-module id="product-list">
<style>
:host {
display: block;
width: 100%;
text-align: center;
}
product-card {
margin-left: 10px;
margin-bottom: 30px;
}
</style>
<template>
<template is="dom-if" if="{{loading}}">
<paper-progress value="10" indeterminate="true" style="width:100%;"></paper-progress>
</template>
<paper-button id="previous" on-tap='previousPage'>Previous</paper-button>
<paper-button id="next" on-tap='nextPage'>Next</paper-button>

<get-products-service products="{{products}}" id="productservice" page="{{page}}" loading="{{loading}}"></get-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: 'product-list',

properties: {
page: {
type: Number,
notify: true,
value: 1
}
},
handleCart: function(event) {

},
previousPage: function(event){
this.page = --this.page;
console.log("page: "+this.page);
},
nextPage: function(event){
this.page = ++this.page;
console.log("page: "+this.page);
}
});
})();
</script>


This is the whole
get-products-service


<dom-module id="get-products-service">
<style>
:host {
display: none;
}
</style>
<template>
<iron-ajax id="productsajax"
url="http://localhost:3003/api/products"
params='{"token":"mytoken"}'
method='GET'
on-response='productsLoaded'
handleAs="json"
loading="{{loading}}" >
</iron-ajax>
</template>
</dom-module>

<script>
(function() {

Polymer({is: 'get-products-service',

properties: {
products: {
type: Array,
notify: true
},
page: {
type: String,
notify: true,
},
perpage: {
type: String,
readOnly: true,
value: "6"
},
loading: {
type: Boolean,
readOnly: true,
notify: true,
value: false
}
},

productsLoaded: function(request) {
console.log(this.$.productsajax.lastResponse);
responseObject = this.$.productsajax.lastResponse;
this.products = responseObject.products;
},

ready: function(){
this.$.productsajax.params.page = this.page;
this.$.productsajax.params.per_page = this.perpage;
},
observers: [
'attributesReady(page)'
],

attributesReady: function(page) {
this.page = page;
this.$.productsajax.params.page = page;
this.$.productsajax.params.per_page = this.perpage;
console.log("service page: "+page);
this.async(function() {
this.$.productsajax.generateRequest();
}, 3000);
}
});
})();
</script>

Answer

Your best option is to separate your concerns. First, your get-products-service:

<dom-module id="get-products-service">
  <style>
    :host {
      display: none;
    }
  </style>
  <template>
    <iron-ajax id="productsajax"
      url="http://localhost:3003/api/products"
      method='GET'
      loading="{{loading}}"
      handleAs="json">
    </iron-ajax>
  </template>

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

      properties: {
        loading: {
          type: Boolean,
          readOnly: true,
          notify: true,
          value: false
        }
      }
    });
  </script>
</dom-module>

Then, in your product-list:

<template>
  <template is="dom-if" if="{{loading}}">
    <paper-progress value="10" indeterminate="true" style="width:100%;"></paper-progress>
  <template>
  <get-products-service loading="{{loading}}"></get-products-service>
</template>

This way get-products-service and paper-progress don't have to know anything about each other, and should be more composable elsewhere in your application.

Comments