|
1 <!DOCTYPE html> |
|
2 <html lang="en"> |
|
3 <head> |
|
4 <meta charset="utf-8"> |
|
5 <title>Example: Reusing a JSONPRequest Instance to Poll a Remote Server</title> |
|
6 <link rel="stylesheet" href="http://fonts.googleapis.com/css?family=PT+Sans:400,700,400italic,700italic"> |
|
7 <link rel="stylesheet" href="../../build/cssgrids/cssgrids-min.css"> |
|
8 <link rel="stylesheet" href="../assets/css/main.css"> |
|
9 <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css"> |
|
10 <link rel="shortcut icon" type="image/png" href="../assets/favicon.png"> |
|
11 <script src="../../build/yui/yui-min.js"></script> |
|
12 |
|
13 </head> |
|
14 <body> |
|
15 <!-- |
|
16 <a href="https://github.com/yui/yui3"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> |
|
17 --> |
|
18 <div id="doc"> |
|
19 <div id="hd"> |
|
20 <h1><img src="http://yuilibrary.com/img/yui-logo.png"></h1> |
|
21 </div> |
|
22 |
|
23 |
|
24 <h1>Example: Reusing a JSONPRequest Instance to Poll a Remote Server</h1> |
|
25 <div class="yui3-g"> |
|
26 <div class="yui3-u-3-4"> |
|
27 <div id="main"> |
|
28 <div class="content"><style scoped> |
|
29 #out { |
|
30 margin-top: 2em; |
|
31 } |
|
32 #out h4 { |
|
33 border-right: 100px solid #ccc; |
|
34 } |
|
35 </style> |
|
36 |
|
37 |
|
38 <div class="intro"> |
|
39 <p> |
|
40 This example shows how to create a reusable JSONPRequest for polling as |
|
41 well as how to configure success and failure callbacks. See the API |
|
42 docs and user guide for a full listing of available configurations. |
|
43 </p> |
|
44 |
|
45 <p> |
|
46 For this example, we will use a JSONP service hosted on <a |
|
47 href="http://yuilibrary.com">YUILibrary</a> to fetch information about |
|
48 a random Gallery module and render some of the information on the page. |
|
49 </p> |
|
50 </div> |
|
51 |
|
52 <div class="example yui3-skin-sam"> |
|
53 <div id="demo"> |
|
54 <input type="button" id="start" value="Start polling"> |
|
55 <input type="button" id="stop" value="Stop polling"> |
|
56 <div id="out"> |
|
57 </div> |
|
58 </div> |
|
59 |
|
60 <script> |
|
61 YUI().use("jsonp", "transition",function (Y) { |
|
62 |
|
63 var url = "http://yuilibrary.com/gallery/api/random?callback={callback}", |
|
64 outputDiv = Y.one("#out"), |
|
65 gallery; |
|
66 |
|
67 // Using the configuration object syntax |
|
68 gallery = new Y.JSONPRequest(url, { |
|
69 on: { |
|
70 success: function (response) { |
|
71 var module = response.modules[0], |
|
72 author = module.owner; |
|
73 |
|
74 // Some users don't have a rank |
|
75 if (!author.rank) { |
|
76 author.rank = "user"; |
|
77 } |
|
78 |
|
79 // Format the author info and store as a property of the |
|
80 // module object for use by Y.Lang.sub |
|
81 // ('this' refers to the JSONPRequest object by default) |
|
82 module.authorHTML = Y.Lang.sub(this.authorTemplate, author); |
|
83 |
|
84 outputDiv.setHTML(Y.Lang.sub(this.moduleTemplate, module)); |
|
85 |
|
86 // Add some flare to the poll interval by showing a "time left" |
|
87 // indicator via the header's border |
|
88 Y.one("#out h4") |
|
89 .setStyle("borderRightWidth", "100px") |
|
90 .transition({ |
|
91 borderRightWidth: 0, |
|
92 duration: 7 |
|
93 }, function () { |
|
94 if (gallery.polling) { |
|
95 gallery.send(); |
|
96 } |
|
97 }); |
|
98 }, |
|
99 |
|
100 failure: function () { |
|
101 gallery.polling = false; |
|
102 outputDiv.setHTML(this.failureTemplate); |
|
103 |
|
104 // Wire up the Try again button |
|
105 outputDiv.one("button").on("click", function () { |
|
106 gallery.send(); |
|
107 }); |
|
108 } |
|
109 } |
|
110 }); |
|
111 |
|
112 |
|
113 gallery.moduleTemplate = |
|
114 '<h4><a href="{url}">{title}</a></h4>' + |
|
115 '<p class="author">{authorHTML}</p>' + |
|
116 '<div>{summary}</div>'; |
|
117 |
|
118 gallery.authorTemplate = |
|
119 '<img src="{icon}" height="30" width="30">' + |
|
120 ' {fullname} <span class="rank">({rank})</span>'; |
|
121 |
|
122 gallery.failureTemplate = |
|
123 '<p class="error">Ack, I couldn\'t reach the Gallery web service!</p>' + |
|
124 '<button>Try again</button>'; |
|
125 |
|
126 gallery.polling = false; |
|
127 |
|
128 |
|
129 // Click the button to send the JSONP request |
|
130 Y.one("#start").on("click", function (e) { |
|
131 if (!gallery.polling) { |
|
132 gallery.polling = true; |
|
133 gallery.send(); |
|
134 } |
|
135 }); |
|
136 |
|
137 Y.one("#stop").on("click", function (e) { |
|
138 gallery.polling = false; |
|
139 }); |
|
140 |
|
141 }); |
|
142 </script> |
|
143 |
|
144 </div> |
|
145 |
|
146 <h3>The data</h3> |
|
147 <p>The structure of the JavaScript object returned from YUILibrary's JSONP service will look like this:</p> |
|
148 |
|
149 <pre class="code prettyprint">{ |
|
150 modules: [ |
|
151 { |
|
152 url: (the url to the module), |
|
153 title: (the title of the module), |
|
154 summary: (short description of the module), |
|
155 ..., |
|
156 owner: { |
|
157 icon: (url to the author's thumb image), |
|
158 fullname: (the author's full name), |
|
159 rank: (YUI Team member?, Contributor? etc), |
|
160 ... |
|
161 } |
|
162 } |
|
163 ], |
|
164 ... |
|
165 }</pre> |
|
166 |
|
167 |
|
168 <p>We'll use these objects to populate an HTML template with data <em>{placeholder}</em>s using <code>Y.Lang.sub( template, object )</code>.</p> |
|
169 |
|
170 |
|
171 <h3>Start simple</h3> |
|
172 <p>To make a single call to the YUILibrary Gallery API, we can just use</p> |
|
173 |
|
174 <pre class="code prettyprint">Y.jsonp("http://yuilibrary.com/gallery/api/random?callback={callback}", handleJSONP);</pre> |
|
175 |
|
176 |
|
177 <p>But since each call to <code>Y.jsonp()</code> creates a new instance of <code>Y.JSONPRequest</code>, we may as well store the instance and reuse it.</p> |
|
178 |
|
179 <pre class="code prettyprint">var gallery = new Y.JSONPRequest("http://yuilibrary.com/gallery/api/random?callback={callback}", handleJSONP); |
|
180 |
|
181 gallery.send();</pre> |
|
182 |
|
183 |
|
184 <h3>Add polling</h3> |
|
185 <p>JSONPRequest doesn't have any built-in polling mechanism, but <code>Y.later()</code> can handle this for us.</p> |
|
186 |
|
187 <pre class="code prettyprint">var url = "http://yuilibrary.com/gallery/api/random?callback={callback}"; |
|
188 |
|
189 function handleJSONP(response) { |
|
190 // populate template from the response object and add to the output div |
|
191 ... |
|
192 |
|
193 Y.one("#out").setHTML( Y.Lang.sub(template, module) ); |
|
194 |
|
195 // After 7 seconds, call the API for a new module |
|
196 Y.later(7000, this, this.send); |
|
197 }; |
|
198 |
|
199 var gallery = new Y.JSONPRequest(url, handleJSONP); |
|
200 gallery.send();</pre> |
|
201 |
|
202 |
|
203 <h3>Add failure protection</h3> |
|
204 <p>In case the Gallery API is busy or some other problem arises, we'll also want to handle this case and display an error. We can do this by passing a configuration object as the second parameter rather than a simple success callback.</p> |
|
205 |
|
206 <pre class="code prettyprint">var gallery = new Y.JSONPRequest(url, { |
|
207 on: { |
|
208 success: function (response) { |
|
209 // populate output div from the template and response object |
|
210 ... |
|
211 |
|
212 Y.one("#out").setHTML( Y.Lang.sub(template, module) ); |
|
213 |
|
214 // After 7 seconds, call the API for a new module |
|
215 Y.later(7000, this, this.send); |
|
216 }, |
|
217 |
|
218 failure: function () { |
|
219 Y.one("#out").setHTML( failureTemplate ); |
|
220 } |
|
221 } |
|
222 }); |
|
223 |
|
224 gallery.send();</pre> |
|
225 |
|
226 |
|
227 <h3>Add flare</h3> |
|
228 <p>Now we'll add a bit of flourish, by adding a visual indicator of how long until the next module is requested. We'll replace the call to <code>Y.later()</code> with a call to <code>node.transition()</code> using a shrinking border to show the remaining time. Then when the transition is complete, we call <code>send()</code> again. |
|
229 |
|
230 <pre class="code prettyprint">var gallery = new Y.JSONPRequest(url, { |
|
231 on: { |
|
232 success: function (response) { |
|
233 // populate output div from the template and response object |
|
234 ... |
|
235 |
|
236 Y.one("#out").setHTML( Y.Lang.sub(template, module) ); |
|
237 |
|
238 // Add some flare to the poll interval by showing a "time left" |
|
239 // indicator via the header's border |
|
240 Y.one("#out h4") |
|
241 .setStyle("borderRightWidth", "100px") |
|
242 .transition({ |
|
243 borderRightWidth: 0, |
|
244 duration: 7 |
|
245 }, function () { |
|
246 gallery.send(); |
|
247 }); |
|
248 }, |
|
249 |
|
250 failure: function () { |
|
251 Y.one("#out").setHTML( failureTemplate ); |
|
252 } |
|
253 } |
|
254 }); |
|
255 |
|
256 gallery.send();</pre> |
|
257 |
|
258 |
|
259 <h3>Stop the poll</h3> |
|
260 <p>The final step is to add the ability to start and stop the polling. We'll manage this by adding a property to the <code>gallery</code> JSONPRequest instance named <code>gallery.polling</code>. See the full code listing below for the implementation. |
|
261 |
|
262 <h3 id="fullcode">Full Code Listing</h3> |
|
263 <h4>HTML</h4> |
|
264 <pre class="code prettyprint"><div id="demo"> |
|
265 <input type="button" id="start" value="Start polling"> |
|
266 <input type="button" id="stop" value="Stop polling"> |
|
267 <div id="out"> |
|
268 </div> |
|
269 </div></pre> |
|
270 |
|
271 |
|
272 <h4>JavaScript</h4> |
|
273 <pre class="code prettyprint"><script> |
|
274 YUI().use("jsonp", "transition",function (Y) { |
|
275 |
|
276 var url = "http://yuilibrary.com/gallery/api/random?callback={callback}", |
|
277 outputDiv = Y.one("#out"), |
|
278 gallery; |
|
279 |
|
280 // Using the configuration object syntax |
|
281 gallery = new Y.JSONPRequest(url, { |
|
282 on: { |
|
283 success: function (response) { |
|
284 var module = response.modules[0], |
|
285 author = module.owner; |
|
286 |
|
287 // Some users don't have a rank |
|
288 if (!author.rank) { |
|
289 author.rank = "user"; |
|
290 } |
|
291 |
|
292 // Format the author info and store as a property of the |
|
293 // module object for use by Y.Lang.sub |
|
294 // ('this' refers to the JSONPRequest object by default) |
|
295 module.authorHTML = Y.Lang.sub(this.authorTemplate, author); |
|
296 |
|
297 outputDiv.setHTML(Y.Lang.sub(this.moduleTemplate, module)); |
|
298 |
|
299 // Add some flare to the poll interval by showing a "time left" |
|
300 // indicator via the header's border |
|
301 Y.one("#out h4") |
|
302 .setStyle("borderRightWidth", "100px") |
|
303 .transition({ |
|
304 borderRightWidth: 0, |
|
305 duration: 7 |
|
306 }, function () { |
|
307 if (gallery.polling) { |
|
308 gallery.send(); |
|
309 } |
|
310 }); |
|
311 }, |
|
312 |
|
313 failure: function () { |
|
314 gallery.polling = false; |
|
315 outputDiv.setHTML(this.failureTemplate); |
|
316 |
|
317 // Wire up the Try again button |
|
318 outputDiv.one("button").on("click", function () { |
|
319 gallery.send(); |
|
320 }); |
|
321 } |
|
322 } |
|
323 }); |
|
324 |
|
325 |
|
326 gallery.moduleTemplate = |
|
327 '<h4><a href="{url}">{title}</a></h4>' + |
|
328 '<p class="author">{authorHTML}</p>' + |
|
329 '<div>{summary}</div>'; |
|
330 |
|
331 gallery.authorTemplate = |
|
332 '<img src="{icon}" height="30" width="30">' + |
|
333 ' {fullname} <span class="rank">({rank})</span>'; |
|
334 |
|
335 gallery.failureTemplate = |
|
336 '<p class="error">Ack, I couldn\'t reach the Gallery web service!</p>' + |
|
337 '<button>Try again</button>'; |
|
338 |
|
339 gallery.polling = false; |
|
340 |
|
341 |
|
342 // Click the button to send the JSONP request |
|
343 Y.one("#start").on("click", function (e) { |
|
344 if (!gallery.polling) { |
|
345 gallery.polling = true; |
|
346 gallery.send(); |
|
347 } |
|
348 }); |
|
349 |
|
350 Y.one("#stop").on("click", function (e) { |
|
351 gallery.polling = false; |
|
352 }); |
|
353 |
|
354 }); |
|
355 </script></pre> |
|
356 |
|
357 </div> |
|
358 </div> |
|
359 </div> |
|
360 |
|
361 <div class="yui3-u-1-4"> |
|
362 <div class="sidebar"> |
|
363 |
|
364 |
|
365 |
|
366 <div class="sidebox"> |
|
367 <div class="hd"> |
|
368 <h2 class="no-toc">Examples</h2> |
|
369 </div> |
|
370 |
|
371 <div class="bd"> |
|
372 <ul class="examples"> |
|
373 |
|
374 |
|
375 <li data-description="Get basic GitHub user info using a Y.jsonp(url, callback)."> |
|
376 <a href="jsonp-github.html">Getting Cross Domain JSON Data Using Y.jsonp()</a> |
|
377 </li> |
|
378 |
|
379 |
|
380 |
|
381 <li data-description="Create a reusable JSONPRequest object to poll the YUILibrary.com Gallery web service, fetching info on a random Gallery module."> |
|
382 <a href="jsonp-gallery.html">Reusing a JSONPRequest Instance to Poll a Remote Server</a> |
|
383 </li> |
|
384 |
|
385 |
|
386 |
|
387 |
|
388 |
|
389 |
|
390 </ul> |
|
391 </div> |
|
392 </div> |
|
393 |
|
394 |
|
395 |
|
396 <div class="sidebox"> |
|
397 <div class="hd"> |
|
398 <h2 class="no-toc">Examples That Use This Component</h2> |
|
399 </div> |
|
400 |
|
401 <div class="bd"> |
|
402 <ul class="examples"> |
|
403 |
|
404 |
|
405 |
|
406 |
|
407 |
|
408 |
|
409 <li data-description="Wrapping async transactions with promises"> |
|
410 <a href="../promise/basic-example.html">Wrapping async transactions with promises</a> |
|
411 </li> |
|
412 |
|
413 |
|
414 |
|
415 <li data-description="Extend Y.Promise to create classes that encapsulate standard transaction logic in descriptive method names"> |
|
416 <a href="../promise/subclass-example.html">Subclassing Y.Promise</a> |
|
417 </li> |
|
418 |
|
419 |
|
420 </ul> |
|
421 </div> |
|
422 </div> |
|
423 |
|
424 </div> |
|
425 </div> |
|
426 </div> |
|
427 </div> |
|
428 |
|
429 <script src="../assets/vendor/prettify/prettify-min.js"></script> |
|
430 <script>prettyPrint();</script> |
|
431 |
|
432 <script> |
|
433 YUI.Env.Tests = { |
|
434 examples: [], |
|
435 project: '../assets', |
|
436 assets: '../assets/jsonp', |
|
437 name: 'jsonp-gallery', |
|
438 title: 'Reusing a JSONPRequest Instance to Poll a Remote Server', |
|
439 newWindow: '', |
|
440 auto: false |
|
441 }; |
|
442 YUI.Env.Tests.examples.push('jsonp-github'); |
|
443 YUI.Env.Tests.examples.push('jsonp-gallery'); |
|
444 YUI.Env.Tests.examples.push('basic-example'); |
|
445 YUI.Env.Tests.examples.push('subclass-example'); |
|
446 |
|
447 </script> |
|
448 <script src="../assets/yui/test-runner.js"></script> |
|
449 |
|
450 |
|
451 |
|
452 </body> |
|
453 </html> |