| OLD | NEW |
| 1 <!-- | 1 <!-- |
| 2 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. | 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 | 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 | 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 | 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 | 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 | 7 subject to an additional IP rights grant found at http://polymer.github.io/PATEN
TS.txt |
| 8 --> | 8 --> |
| 9 | 9 |
| 10 <link rel="import" href="../polymer/polymer.html"> | 10 <link rel="import" href="../polymer/polymer.html"> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 | 23 |
| 24 With `auto` set to `true`, the element performs a request whenever | 24 With `auto` set to `true`, the element performs a request whenever |
| 25 its `url`, `params` or `body` properties are changed. Automatically generated | 25 its `url`, `params` or `body` properties are changed. Automatically generated |
| 26 requests will be debounced in the case that multiple attributes are changed | 26 requests will be debounced in the case that multiple attributes are changed |
| 27 sequentially. | 27 sequentially. |
| 28 | 28 |
| 29 Note: The `params` attribute must be double quoted JSON. | 29 Note: The `params` attribute must be double quoted JSON. |
| 30 | 30 |
| 31 You can trigger a request explicitly by calling `generateRequest` on the | 31 You can trigger a request explicitly by calling `generateRequest` on the |
| 32 element. | 32 element. |
| 33 |
| 34 @demo demo/index.html |
| 33 --> | 35 --> |
| 34 | 36 |
| 35 <script> | 37 <script> |
| 36 | 38 |
| 37 Polymer({ | 39 Polymer({ |
| 38 | 40 |
| 39 is: 'iron-ajax', | 41 is: 'iron-ajax', |
| 40 | 42 |
| 41 /** | 43 /** |
| 42 * Fired when a request is sent. | 44 * Fired when a request is sent. |
| (...skipping 17 matching lines...) Expand all Loading... |
| 60 /** | 62 /** |
| 61 * The URL target of the request. | 63 * The URL target of the request. |
| 62 */ | 64 */ |
| 63 url: { | 65 url: { |
| 64 type: String, | 66 type: String, |
| 65 value: '' | 67 value: '' |
| 66 }, | 68 }, |
| 67 | 69 |
| 68 /** | 70 /** |
| 69 * An object that contains query parameters to be appended to the | 71 * An object that contains query parameters to be appended to the |
| 70 * specified `url` when generating a request. | 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. |
| 71 */ | 75 */ |
| 72 params: { | 76 params: { |
| 73 type: Object, | 77 type: Object, |
| 74 value: function() { | 78 value: function() { |
| 75 return {}; | 79 return {}; |
| 76 } | 80 } |
| 77 }, | 81 }, |
| 78 | 82 |
| 79 /** | 83 /** |
| 80 * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'. | 84 * The HTTP method to use such as 'GET', 'POST', 'PUT', or 'DELETE'. |
| 81 * Default is 'GET'. | 85 * Default is 'GET'. |
| 82 */ | 86 */ |
| 83 method: { | 87 method: { |
| 84 type: String, | 88 type: String, |
| 85 value: 'GET' | 89 value: 'GET' |
| 86 }, | 90 }, |
| 87 | 91 |
| 88 /** | 92 /** |
| 89 * HTTP request headers to send. | 93 * HTTP request headers to send. |
| 90 * | 94 * |
| 91 * Example: | 95 * Example: |
| 92 * | 96 * |
| 93 * <iron-ajax | 97 * <iron-ajax |
| 94 * auto | 98 * auto |
| 95 * url="http://somesite.com" | 99 * url="http://somesite.com" |
| 96 * headers='{"X-Requested-With": "XMLHttpRequest"}' | 100 * headers='{"X-Requested-With": "XMLHttpRequest"}' |
| 97 * handle-as="json" | 101 * handle-as="json" |
| 98 * last-response-changed="{{handleResponse}}"></iron-ajax> | 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. |
| 99 */ | 106 */ |
| 100 headers: { | 107 headers: { |
| 101 type: Object, | 108 type: Object, |
| 102 value: function() { | 109 value: function() { |
| 103 return {}; | 110 return {}; |
| 104 } | 111 } |
| 105 }, | 112 }, |
| 106 | 113 |
| 107 /** | 114 /** |
| 108 * Content type to use when sending data. If the contenttype is set | 115 * Content type to use when sending data. If the `contentType` property |
| 109 * and a `Content-Type` header is specified in the `headers` attribute, | 116 * is set and a `Content-Type` header is specified in the `headers` |
| 110 * the `headers` attribute value will take precedence. | 117 * property, the `headers` property value will take precedence. |
| 111 */ | 118 */ |
| 112 contentType: { | 119 contentType: { |
| 113 type: String, | 120 type: String, |
| 114 value: 'application/x-www-form-urlencoded' | 121 value: 'application/x-www-form-urlencoded' |
| 115 }, | 122 }, |
| 116 | 123 |
| 117 /** | 124 /** |
| 118 * Optional raw body content to send when method === "POST". | 125 * Optional raw body content to send when method === "POST". |
| 119 * | 126 * |
| 120 * Example: | 127 * Example: |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 */ | 207 */ |
| 201 lastRequest: { | 208 lastRequest: { |
| 202 type: Object, | 209 type: Object, |
| 203 notify: true, | 210 notify: true, |
| 204 readOnly: true | 211 readOnly: true |
| 205 }, | 212 }, |
| 206 | 213 |
| 207 /** | 214 /** |
| 208 * Will be set to the most recent response received by a request | 215 * Will be set to the most recent response received by a request |
| 209 * that originated from this iron-ajax element. The type of the response | 216 * that originated from this iron-ajax element. The type of the response |
| 210 * is determined by the value of `handleas` at the time that the request | 217 * is determined by the value of `handleAs` at the time that the request |
| 211 * was generated. | 218 * was generated. |
| 212 */ | 219 */ |
| 213 lastResponse: { | 220 lastResponse: { |
| 214 type: Object, | 221 type: Object, |
| 215 notify: true, | 222 notify: true, |
| 216 readOnly: true | 223 readOnly: true |
| 217 }, | 224 }, |
| 218 | 225 |
| 219 /** | 226 /** |
| 220 * Will be set to the most recent error that resulted from a request | 227 * Will be set to the most recent error that resulted from a request |
| 221 * that originated from this iron-ajax element. | 228 * that originated from this iron-ajax element. |
| 222 */ | 229 */ |
| 223 lastError: { | 230 lastError: { |
| 224 type: Object, | 231 type: Object, |
| 225 notify: true, | 232 notify: true, |
| 226 readOnly: true | 233 readOnly: true |
| 227 }, | 234 }, |
| 228 | 235 |
| 229 /** | 236 /** |
| 230 * An Array of all in-flight requests originating from this iron-ajax | 237 * An Array of all in-flight requests originating from this iron-ajax |
| 231 * element. | 238 * element. |
| 232 */ | 239 */ |
| 233 activeRequests: { | 240 activeRequests: { |
| 234 type: Array, | 241 type: Array, |
| 235 notify: true, | 242 notify: true, |
| 236 readOnly: true, | 243 readOnly: true, |
| 237 value: function() { | 244 value: function() { |
| 238 this._setActiveRequests([]); | 245 return []; |
| 239 } | 246 } |
| 240 }, | 247 }, |
| 241 | 248 |
| 242 /** | 249 /** |
| 243 * Length of time in milliseconds to debounce multiple requests. | 250 * Length of time in milliseconds to debounce multiple requests. |
| 244 */ | 251 */ |
| 245 debounceDuration: { | 252 debounceDuration: { |
| 246 type: Number, | 253 type: Number, |
| 247 value: 0, | 254 value: 0, |
| 248 notify: true | 255 notify: true |
| 249 }, | 256 }, |
| 250 | 257 |
| 251 _boundHandleResponse: { | 258 _boundHandleResponse: { |
| 252 type: Function, | 259 type: Function, |
| 253 value: function() { | 260 value: function() { |
| 254 return this.handleResponse.bind(this); | 261 return this._handleResponse.bind(this); |
| 255 } | |
| 256 }, | |
| 257 | |
| 258 _boundDiscardRequest: { | |
| 259 type: Function, | |
| 260 value: function() { | |
| 261 return this.discardRequest.bind(this); | |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 }, | 264 }, |
| 265 | 265 |
| 266 observers: [ | 266 observers: [ |
| 267 'requestOptionsChanged(url, method, params, headers,' + | 267 '_requestOptionsChanged(url, method, params, headers,' + |
| 268 'contentType, body, sync, handleAs, withCredentials, auto)' | 268 'contentType, body, sync, handleAs, withCredentials, auto)' |
| 269 ], | 269 ], |
| 270 | 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 */ |
| 271 get queryString () { | 277 get queryString () { |
| 272 var queryParts = []; | 278 var queryParts = []; |
| 273 var param; | 279 var param; |
| 274 var value; | 280 var value; |
| 275 | 281 |
| 276 for (param in this.params) { | 282 for (param in this.params) { |
| 277 value = this.params[param]; | 283 value = this.params[param]; |
| 278 param = window.encodeURIComponent(param); | 284 param = window.encodeURIComponent(param); |
| 279 | 285 |
| 280 if (value !== null) { | 286 if (value !== null) { |
| 281 param += '=' + window.encodeURIComponent(value); | 287 param += '=' + window.encodeURIComponent(value); |
| 282 } | 288 } |
| 283 | 289 |
| 284 queryParts.push(param); | 290 queryParts.push(param); |
| 285 } | 291 } |
| 286 | 292 |
| 287 return queryParts.join('&'); | 293 return queryParts.join('&'); |
| 288 }, | 294 }, |
| 289 | 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 */ |
| 290 get requestUrl() { | 302 get requestUrl() { |
| 291 var queryString = this.queryString; | 303 var queryString = this.queryString; |
| 292 | 304 |
| 293 if (queryString) { | 305 if (queryString) { |
| 294 return this.url + '?' + queryString; | 306 return this.url + '?' + queryString; |
| 295 } | 307 } |
| 296 | 308 |
| 297 return this.url; | 309 return this.url; |
| 298 }, | 310 }, |
| 299 | 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 */ |
| 300 get requestHeaders() { | 319 get requestHeaders() { |
| 301 var headers = { | 320 var headers = { |
| 302 'content-type': this.contentType | 321 'Content-Type': this.contentType |
| 303 }; | 322 }; |
| 304 var header; | 323 var header; |
| 305 | 324 |
| 306 if (this.headers instanceof Object) { | 325 if (this.headers instanceof Object) { |
| 307 for (header in this.headers) { | 326 for (header in this.headers) { |
| 308 headers[header] = this.headers[header].toString(); | 327 headers[header] = this.headers[header].toString(); |
| 309 } | 328 } |
| 310 } | 329 } |
| 311 | 330 |
| 312 return headers; | 331 return headers; |
| 313 }, | 332 }, |
| 314 | 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 */ |
| 315 toRequestOptions: function() { | 347 toRequestOptions: function() { |
| 316 return { | 348 return { |
| 317 url: this.requestUrl, | 349 url: this.requestUrl, |
| 318 method: this.method, | 350 method: this.method, |
| 319 headers: this.requestHeaders, | 351 headers: this.requestHeaders, |
| 320 body: this.body, | 352 body: this.body, |
| 321 async: !this.sync, | 353 async: !this.sync, |
| 322 handleAs: this.handleAs, | 354 handleAs: this.handleAs, |
| 323 withCredentials: this.withCredentials | 355 withCredentials: this.withCredentials |
| 324 }; | 356 }; |
| 325 }, | 357 }, |
| 326 | 358 |
| 327 requestOptionsChanged: function() { | |
| 328 this.debounce('generate-request', function() { | |
| 329 if (!this.url && this.url !== '') { | |
| 330 return; | |
| 331 } | |
| 332 | |
| 333 if (this.auto) { | |
| 334 this.generateRequest(); | |
| 335 } | |
| 336 }, this.debounceDuration); | |
| 337 }, | |
| 338 | |
| 339 /** | 359 /** |
| 340 * Performs an AJAX request to the specified URL. | 360 * Performs an AJAX request to the specified URL. |
| 341 * | 361 * |
| 342 * @method generateRequest | 362 * @return {!IronRequestElement} |
| 343 */ | 363 */ |
| 344 generateRequest: function() { | 364 generateRequest: function() { |
| 345 var request = document.createElement('iron-request'); | 365 var request = /** @type {!IronRequestElement} */ (document.createElement('
iron-request')); |
| 346 var requestOptions = this.toRequestOptions(); | 366 var requestOptions = this.toRequestOptions(); |
| 347 | 367 |
| 348 this.activeRequests.push(request); | 368 this.activeRequests.push(request); |
| 349 | 369 |
| 350 request.completes.then( | 370 request.completes.then( |
| 351 this._boundHandleResponse | 371 this._boundHandleResponse |
| 352 ).catch( | 372 ).catch( |
| 353 this.handleError.bind(this, request) | 373 this._handleError.bind(this, request) |
| 354 ).then( | 374 ).then( |
| 355 this._boundDiscardRequest | 375 this._discardRequest.bind(this, request) |
| 356 ); | 376 ); |
| 357 | 377 |
| 358 request.send(requestOptions); | 378 request.send(requestOptions); |
| 359 | 379 |
| 360 this._setLastRequest(request); | 380 this._setLastRequest(request); |
| 381 this._setLoading(true); |
| 361 | 382 |
| 362 this.fire('request', { | 383 this.fire('request', { |
| 363 request: request, | 384 request: request, |
| 364 options: requestOptions | 385 options: requestOptions |
| 365 }); | 386 }); |
| 366 | 387 |
| 367 return request; | 388 return request; |
| 368 }, | 389 }, |
| 369 | 390 |
| 370 handleResponse: function(request) { | 391 _handleResponse: function(request) { |
| 371 this._setLastResponse(request.response); | 392 this._setLastResponse(request.response); |
| 372 this.fire('response', request); | 393 this.fire('response', request); |
| 373 }, | 394 }, |
| 374 | 395 |
| 375 handleError: function(request, error) { | 396 _handleError: function(request, error) { |
| 376 if (this.verbose) { | 397 if (this.verbose) { |
| 377 console.error(error); | 398 console.error(error); |
| 378 } | 399 } |
| 379 | 400 |
| 380 this._setLastError({ | 401 this._setLastError({ |
| 381 request: request, | 402 request: request, |
| 382 error: error | 403 error: error |
| 383 }); | 404 }); |
| 384 this.fire('error', { | 405 this.fire('error', { |
| 385 request: request, | 406 request: request, |
| 386 error: error | 407 error: error |
| 387 }); | 408 }); |
| 388 }, | 409 }, |
| 389 | 410 |
| 390 discardRequest: function(request) { | 411 _discardRequest: function(request) { |
| 391 var requestIndex = this.activeRequests.indexOf(request); | 412 var requestIndex = this.activeRequests.indexOf(request); |
| 392 | 413 |
| 393 if (requestIndex > 0) { | 414 if (requestIndex > -1) { |
| 394 this.activeRequests.splice(requestIndex, 1); | 415 this.activeRequests.splice(requestIndex, 1); |
| 395 } | 416 } |
| 396 } | 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 |
| 397 }); | 435 }); |
| 398 </script> | 436 </script> |
| OLD | NEW |