jack jack - 3 months ago 46
Ajax Question

Polymer 1.0: Wait for multiple iron-ajax requests to finish

I have multiple iron-ajax tags on the page e.g.:

<iron-ajax
auto
id="ajaxCall1"
url="/data/test1.json"
handle-as="json"
on-response="_myAjaxCall1ResponseHandler"
last-response="{{_myAjaxCall1LastResponse}}"
debounce-duration="300">
</iron-ajax>

<iron-ajax
auto
id="ajaxCall2"
url="/data/test2.json"
handle-as="json"
on-response="_myAjaxCall2ResponseHandler"
last-response="{{_myAjaxCall2LastResponse}}"
debounce-duration="300">
</iron-ajax>


How can I wait for both requests to be completed before I do another action? I don't care about the order of requests, just they they are both completed.

Thanks.

Answer

Observing multiple properties triggers the observer only when both become defined. Thus, if you observe both responses bound to last-response it will fire only once both requests are finished.

Polymer({
  observers: [
    '_requestsFinished(_myAjaxCall1LastResponse, _myAjaxCall2LastResponse)'
  ],
  _requestsFinished: function(res1, res2) {
    // will only fire when res1 and res2 are non-undefined
  }
});

The trick is to unset the properties before requests are triggered again so that the observer waits for both to become defined again. See the snippet below.

Polymer({
  is: 'my-elem',
  properties: {
    prop1: Object,
    prop2: Object,
    observer: {
      value: 'not fired'
    }
  },
  observers: [
    'observeBoth(prop1, prop2)'
  ],
  observeBoth: function(prop1, prop2) {
    console.log('observer');
    this.observer = 'fired';
  },
  set1: function() {
    console.log('prop1');
    this.prop1 = 'x';
  },
  set2: function() {
    console.log('prop2');
    this.prop2 = 'x';
  },
  unset: function() {
    this.prop1 = undefined;
    this.prop2 = undefined;
    this.observer = 'not fired';
  }
});
<!DOCTYPE html>
<html>
<head>
  <base href="https://polygit.org/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import"/>
</head>

<body>
  <my-elem></my-elem>
  
  <dom-module id="my-elem">
    <template>
      Observer: {{observer}}
      <br>
      <input type="button" value="set prop1" on-tap="set1" />
      <input type="button" value="set prop2" on-tap="set2" />
      <input type="button" value="unset props" on-tap="unset" />
    </template>
  </dom-module>

</body>
</html>

Comments