| OLD | NEW |
| (Empty) |
| 1 <!-- | |
| 2 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | |
| 3 This code may only be used under the BSD style license found at http://polymer.g
ithub.io/LICENSE.txt | |
| 4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt | |
| 5 The complete set of contributors may be found at http://polymer.github.io/CONTRI
BUTORS.txt | |
| 6 Code distributed by Google as part of the polymer project is also | |
| 7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt | |
| 8 --> | |
| 9 | |
| 10 <link rel="import" href="../polymer/polymer.html"> | |
| 11 <link rel="import" href="iron-request.html"> | |
| 12 | |
| 13 <!-- | |
| 14 The `iron-ajax` element exposes network request functionality. | |
| 15 | |
| 16 <iron-ajax | |
| 17 auto | |
| 18 url="http://gdata.youtube.com/feeds/api/videos/" | |
| 19 params='{"alt":"json", "q":"chrome"}' | |
| 20 handle-as="json" | |
| 21 on-response="handleResponse" | |
| 22 debounce-duration="300"></iron-ajax> | |
| 23 | |
| 24 With `auto` set to `true`, the element performs a request whenever | |
| 25 its `url`, `params` or `body` properties are changed. Automatically generated | |
| 26 requests will be debounced in the case that multiple attributes are changed | |
| 27 sequentially. | |
| 28 | |
| 29 Note: The `params` attribute must be double quoted JSON. | |
| 30 | |
| 31 You can trigger a request explicitly by calling `generateRequest` on the | |
| 32 element. | |
| 33 | |
| 34 @demo demo/index.html | |
| 35 --> | |
| 36 | |
| 37 <script> | |
| 38 | |
| 39 Polymer({ | |
| 40 | |
| 41 is: 'iron-ajax', | |
| 42 | |
| 43 /** | |
| 44 * Fired when a request is sent. | |
| 45 * | |
| 46 * @event request | |
| 47 */ | |
| 48 | |
| 49 /** | |
| 50 * Fired when a response is received. | |
| 51 * | |
| 52 * @event response | |
| 53 */ | |
| 54 | |
| 55 /** | |
| 56 * Fired when an error is received. | |
| 57 * | |
| 58 * @event error | |
| 59 */ | |
| 60 | |
| 61 properties: { | |
| 62 /** | |
| 63 * The URL target of the request. | |
| 64 */ | |
| 65 url: { | |
| 66 type: String, | |
| 67 value: '' | |
| 68 }, | |
| 69 | |
| 70 /** | |
| 71 * An object that contains query parameters to be appended to the | |
| 72 * specified `url` when generating a request. If you wish to set the body | |
| 73 * content when making a POST request, you should use the `body` property | |
| 74 * instead. | |
| 75 */ | |
| 76 params: { | |
| 77 type: Object, | |
| 78 value: function() { | |
| 79 return {}; | |
| 80 } | |
| 81 }, | |
| 82 | |
| 83 /** | |
| 84 * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'. | |
| 85 * Default is 'GET'. | |
| 86 */ | |
| 87 method: { | |
| 88 type: String, | |
| 89 value: 'GET' | |
| 90 }, | |
| 91 | |
| 92 /** | |
| 93 * HTTP request headers to send. | |
| 94 * | |
| 95 * Example: | |
| 96 * | |
| 97 * <iron-ajax | |
| 98 * auto | |
| 99 * url="http://somesite.com" | |
| 100 * headers='{"X-Requested-With": "XMLHttpRequest"}' | |
| 101 * handle-as="json" | |
| 102 * last-response-changed="{{handleResponse}}"></iron-ajax> | |
| 103 * | |
| 104 * Note: setting a `Content-Type` header here will override the value | |
| 105 * specified by the `contentType` property of this element. | |
| 106 */ | |
| 107 headers: { | |
| 108 type: Object, | |
| 109 value: function() { | |
| 110 return {}; | |
| 111 } | |
| 112 }, | |
| 113 | |
| 114 /** | |
| 115 * Content type to use when sending data. If the `contentType` property | |
| 116 * is set and a `Content-Type` header is specified in the `headers` | |
| 117 * property, the `headers` property value will take precedence. | |
| 118 */ | |
| 119 contentType: { | |
| 120 type: String, | |
| 121 value: 'application/x-www-form-urlencoded' | |
| 122 }, | |
| 123 | |
| 124 /** | |
| 125 * Optional raw body content to send when method === "POST". | |
| 126 * | |
| 127 * Example: | |
| 128 * | |
| 129 * <iron-ajax method="POST" auto url="http://somesite.com" | |
| 130 * body='{"foo":1, "bar":2}'> | |
| 131 * </iron-ajax> | |
| 132 */ | |
| 133 body: { | |
| 134 type: String, | |
| 135 value: '' | |
| 136 }, | |
| 137 | |
| 138 /** | |
| 139 * Toggle whether XHR is synchronous or asynchronous. Don't change this | |
| 140 * to true unless You Know What You Are Doing™. | |
| 141 */ | |
| 142 sync: { | |
| 143 type: Boolean, | |
| 144 value: false | |
| 145 }, | |
| 146 | |
| 147 /** | |
| 148 * Specifies what data to store in the `response` property, and | |
| 149 * to deliver as `event.response` in `response` events. | |
| 150 * | |
| 151 * One of: | |
| 152 * | |
| 153 * `text`: uses `XHR.responseText`. | |
| 154 * | |
| 155 * `xml`: uses `XHR.responseXML`. | |
| 156 * | |
| 157 * `json`: uses `XHR.responseText` parsed as JSON. | |
| 158 * | |
| 159 * `arraybuffer`: uses `XHR.response`. | |
| 160 * | |
| 161 * `blob`: uses `XHR.response`. | |
| 162 * | |
| 163 * `document`: uses `XHR.response`. | |
| 164 */ | |
| 165 handleAs: { | |
| 166 type: String, | |
| 167 value: 'json' | |
| 168 }, | |
| 169 | |
| 170 /** | |
| 171 * Set the withCredentials flag on the request. | |
| 172 */ | |
| 173 withCredentials: { | |
| 174 type: Boolean, | |
| 175 value: false | |
| 176 }, | |
| 177 | |
| 178 /** | |
| 179 * If true, automatically performs an Ajax request when either `url` or | |
| 180 * `params` changes. | |
| 181 */ | |
| 182 auto: { | |
| 183 type: Boolean, | |
| 184 value: false | |
| 185 }, | |
| 186 | |
| 187 /** | |
| 188 * If true, error messages will automatically be logged to the console. | |
| 189 */ | |
| 190 verbose: { | |
| 191 type: Boolean, | |
| 192 value: false | |
| 193 }, | |
| 194 | |
| 195 /** | |
| 196 * Will be set to true if there is at least one in-flight request | |
| 197 * associated with this iron-ajax element. | |
| 198 */ | |
| 199 loading: { | |
| 200 type: Boolean, | |
| 201 notify: true, | |
| 202 readOnly: true | |
| 203 }, | |
| 204 | |
| 205 /** | |
| 206 * Will be set to the most recent request made by this iron-ajax element. | |
| 207 */ | |
| 208 lastRequest: { | |
| 209 type: Object, | |
| 210 notify: true, | |
| 211 readOnly: true | |
| 212 }, | |
| 213 | |
| 214 /** | |
| 215 * Will be set to the most recent response received by a request | |
| 216 * that originated from this iron-ajax element. The type of the response | |
| 217 * is determined by the value of `handleAs` at the time that the request | |
| 218 * was generated. | |
| 219 */ | |
| 220 lastResponse: { | |
| 221 type: Object, | |
| 222 notify: true, | |
| 223 readOnly: true | |
| 224 }, | |
| 225 | |
| 226 /** | |
| 227 * Will be set to the most recent error that resulted from a request | |
| 228 * that originated from this iron-ajax element. | |
| 229 */ | |
| 230 lastError: { | |
| 231 type: Object, | |
| 232 notify: true, | |
| 233 readOnly: true | |
| 234 }, | |
| 235 | |
| 236 /** | |
| 237 * An Array of all in-flight requests originating from this iron-ajax | |
| 238 * element. | |
| 239 */ | |
| 240 activeRequests: { | |
| 241 type: Array, | |
| 242 notify: true, | |
| 243 readOnly: true, | |
| 244 value: function() { | |
| 245 return []; | |
| 246 } | |
| 247 }, | |
| 248 | |
| 249 /** | |
| 250 * Length of time in milliseconds to debounce multiple requests. | |
| 251 */ | |
| 252 debounceDuration: { | |
| 253 type: Number, | |
| 254 value: 0, | |
| 255 notify: true | |
| 256 }, | |
| 257 | |
| 258 _boundHandleResponse: { | |
| 259 type: Function, | |
| 260 value: function() { | |
| 261 return this._handleResponse.bind(this); | |
| 262 } | |
| 263 } | |
| 264 }, | |
| 265 | |
| 266 observers: [ | |
| 267 '_requestOptionsChanged(url, method, params, headers,' + | |
| 268 'contentType, body, sync, handleAs, withCredentials, auto)' | |
| 269 ], | |
| 270 | |
| 271 /** | |
| 272 * The query string that should be appended to the `url`, serialized from | |
| 273 * the current value of `params`. | |
| 274 * | |
| 275 * @return {string} | |
| 276 */ | |
| 277 get queryString () { | |
| 278 var queryParts = []; | |
| 279 var param; | |
| 280 var value; | |
| 281 | |
| 282 for (param in this.params) { | |
| 283 value = this.params[param]; | |
| 284 param = window.encodeURIComponent(param); | |
| 285 | |
| 286 if (value !== null) { | |
| 287 param += '=' + window.encodeURIComponent(value); | |
| 288 } | |
| 289 | |
| 290 queryParts.push(param); | |
| 291 } | |
| 292 | |
| 293 return queryParts.join('&'); | |
| 294 }, | |
| 295 | |
| 296 /** | |
| 297 * The `url` with query string (if `params` are specified), suitable for | |
| 298 * providing to an `iron-request` instance. | |
| 299 * | |
| 300 * @return {string} | |
| 301 */ | |
| 302 get requestUrl() { | |
| 303 var queryString = this.queryString; | |
| 304 | |
| 305 if (queryString) { | |
| 306 return this.url + '?' + queryString; | |
| 307 } | |
| 308 | |
| 309 return this.url; | |
| 310 }, | |
| 311 | |
| 312 /** | |
| 313 * An object that maps header names to header values, first applying the | |
| 314 * the value of `Content-Type` and then overlaying the headers specified | |
| 315 * in the `headers` property. | |
| 316 * | |
| 317 * @return {Object} | |
| 318 */ | |
| 319 get requestHeaders() { | |
| 320 var headers = { | |
| 321 'Content-Type': this.contentType | |
| 322 }; | |
| 323 var header; | |
| 324 | |
| 325 if (this.headers instanceof Object) { | |
| 326 for (header in this.headers) { | |
| 327 headers[header] = this.headers[header].toString(); | |
| 328 } | |
| 329 } | |
| 330 | |
| 331 return headers; | |
| 332 }, | |
| 333 | |
| 334 /** | |
| 335 * Request options suitable for generating an `iron-request` instance based | |
| 336 * on the current state of the `iron-ajax` instance's properties. | |
| 337 * | |
| 338 * @return {{ | |
| 339 * url: string, | |
| 340 * method: (string|undefined), | |
| 341 * async: (boolean|undefined), | |
| 342 * body: (ArrayBuffer|ArrayBufferView|Blob|Document|FormData|null|string|u
ndefined), | |
| 343 * headers: (Object|undefined), | |
| 344 * handleAs: (string|undefined), | |
| 345 * withCredentials: (boolean|undefined)}} | |
| 346 */ | |
| 347 toRequestOptions: function() { | |
| 348 return { | |
| 349 url: this.requestUrl, | |
| 350 method: this.method, | |
| 351 headers: this.requestHeaders, | |
| 352 body: this.body, | |
| 353 async: !this.sync, | |
| 354 handleAs: this.handleAs, | |
| 355 withCredentials: this.withCredentials | |
| 356 }; | |
| 357 }, | |
| 358 | |
| 359 /** | |
| 360 * Performs an AJAX request to the specified URL. | |
| 361 * | |
| 362 * @return {!IronRequestElement} | |
| 363 */ | |
| 364 generateRequest: function() { | |
| 365 var request = /** @type {!IronRequestElement} */ (document.createElement('
iron-request')); | |
| 366 var requestOptions = this.toRequestOptions(); | |
| 367 | |
| 368 this.activeRequests.push(request); | |
| 369 | |
| 370 request.completes.then( | |
| 371 this._boundHandleResponse | |
| 372 ).catch( | |
| 373 this._handleError.bind(this, request) | |
| 374 ).then( | |
| 375 this._discardRequest.bind(this, request) | |
| 376 ); | |
| 377 | |
| 378 request.send(requestOptions); | |
| 379 | |
| 380 this._setLastRequest(request); | |
| 381 this._setLoading(true); | |
| 382 | |
| 383 this.fire('request', { | |
| 384 request: request, | |
| 385 options: requestOptions | |
| 386 }); | |
| 387 | |
| 388 return request; | |
| 389 }, | |
| 390 | |
| 391 _handleResponse: function(request) { | |
| 392 this._setLastResponse(request.response); | |
| 393 this.fire('response', request); | |
| 394 }, | |
| 395 | |
| 396 _handleError: function(request, error) { | |
| 397 if (this.verbose) { | |
| 398 console.error(error); | |
| 399 } | |
| 400 | |
| 401 this._setLastError({ | |
| 402 request: request, | |
| 403 error: error | |
| 404 }); | |
| 405 this.fire('error', { | |
| 406 request: request, | |
| 407 error: error | |
| 408 }); | |
| 409 }, | |
| 410 | |
| 411 _discardRequest: function(request) { | |
| 412 var requestIndex = this.activeRequests.indexOf(request); | |
| 413 | |
| 414 if (requestIndex > -1) { | |
| 415 this.activeRequests.splice(requestIndex, 1); | |
| 416 } | |
| 417 | |
| 418 if (this.activeRequests.length === 0) { | |
| 419 this._setLoading(false); | |
| 420 } | |
| 421 }, | |
| 422 | |
| 423 _requestOptionsChanged: function() { | |
| 424 this.debounce('generate-request', function() { | |
| 425 if (!this.url && this.url !== '') { | |
| 426 return; | |
| 427 } | |
| 428 | |
| 429 if (this.auto) { | |
| 430 this.generateRequest(); | |
| 431 } | |
| 432 }, this.debounceDuration); | |
| 433 }, | |
| 434 | |
| 435 }); | |
| 436 </script> | |
| OLD | NEW |