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