Search code examples
javascriptajaxpolymerpolymer-1.0

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>

Solution

  • 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.