<!--#include virtual="../s5/commontop.html" -->
<title>Lecture 14: JSONP & APIs — INFO 343 Autumn 2012</title>
</head>
<body>
<div class="layout">
<div id="controls"><!-- DO NOT EDIT --></div>
<div id="currentSlide"><!-- DO NOT EDIT --></div>
<div id="header"></div>
<div id="footer">
<h1>INFO 343 Lecture 14</h1>
<h2>JSONP & APIs</h2>
</div>
</div>
<div class="presentation">
<div class="slide">
<h1>JSONP & APIs</h1>
<h3>Lecture 14</h3>
<!-- <h4>Reading: 10.3–10.4</h4> -->
<p class="license">
© 2012 Morgan Doocy
</p>
<div class="w3c">
<a href="http://validator.w3.org/check/referer"><img src="../s5/images/w3c-xhtml11.png" alt="Valid XHTML 1.1" /></a>
<a href="http://jigsaw.w3.org/css-validator/check/referer"><img src="../s5/images/w3c-css.png" alt="Valid CSS!" /></a>
</div>
</div>
<div class="slide">
<h1>The Twitter Developers’ API</h1>
<p class="description"><a href="https://dev.twitter.com/docs">https://dev.twitter.com/docs</a></p>
<div style="float: right; width: 30%"><img src="developer.png"></div>
<ul>
<li>Developer tools for fetching & embedding Twitter data
<ul>
<li>Specify search terms</li>
<li>Get tweets in JSON or XML</li>
<li>Embed tweets in your page</li>
<li>Get a user’s Twitter feed</li>
<li>etc.</li>
</ul>
</li>
<li>More detailed features require an <a href="https://dev.twitter.com/docs/auth/tokens-devtwittercom">authentication token</a></li>
<li>Most web service data is accessed using the <a href="https://dev.twitter.com/docs/api/1.1">REST API</a></li>
<li>We’ll use the <a href="https://dev.twitter.com/docs/api/1/get/search">older search API</a> because it doesn’t require authentication</li>
</ul>
</div>
<div class="slide">
<h1>Problem: Loading data from another domain</h1>
<pre class="examplecode js">
$.get('http://<em>search.twitter.com</em>/search.json?q=beer', function(data) {
<span class="comment">// never gonna happen :(</span>
alert('Got data from Twitter!');
});
</pre>
<ul>
<li>Services like Google Maps, Twitter, etc. provide data in XML/JSON via web services</li>
<li>We’d like to use that data in our JS application</li>
<li>But browser blocks Ajax requests to other domains!
<ul>
<li>Called the <i>Same-Origin Policy</i></li>
</ul>
</li>
</ul>
</div>
<div class="slide">
<h1>Solution: <a href="http://bob.ippoli.to/archives/2005/12/05/remote-json-jsonp/">JSONP</a></h1>
<p class="description">A “cooperative cheat” to load data from another domain</p>
<pre class="syntaxtemplate js">
$.ajax('<var>url of web service on a different domain</var>', {
<em>dataType: 'jsonp'</em>,
success: <var>functionName</var>
});
</pre>
<p>This causes jQuery to dynamically inject this <code>script</code> tag:</p>
<pre class="syntaxtemplate html">
<script src="<var>url of web service on a different domain</var><em>?callback=<var>functionName</var></em>"></script>
</pre>
<p>If the web service supports the <code>callback</code> parameter, its output will be a JS call our <var>functionName</var> function, passing the data to it:</p>
<pre class="syntaxtemplate js">
<var>functionName</var>(<var>JS object data</var>);
</pre>
</div>
<div class="slide">
<h1>Inspecting JSON results</h1>
<div style="float: right; width: 60%"><img src="firebug-net-json.png" style="width: 100%" alt="Inspecting a JSONP result using Firebug's Net tab" /></div>
<ul>
<li>Use Firebug’s Net tab to inspect the JSONP request
<ul>
<li>(Won’t show up under Console since it isn’t a real Ajax request)</li>
</ul>
</li>
<li>Neatly formats the fields and values in the JSON response</li>
</ul>
</div>
<div class="slide">
<h1>Example: Loading tweets using JSONP</h1>
<div class="example">
<pre class="examplecode js">
$.ajax('<em>http://search.twitter.com/search.json</em>', {
<em>data: { q: 'beer' },</em>
<em>dataType: 'jsonp',</em>
success: injectTweets
});
function injectTweets(<em>data</em>) {
for (var i = 0; i < data.results.length; i++) {
var tweet = data.results[i]; <span class="comment">// the ith tweet in the results list</span>
<span class="comment">// do something with this tweet</span>
}
}
</pre>
</div>
<ul>
<li>Make request using <code>dataType: 'jsonp'</code> to get around the same-origin policy</li>
<li>Inspect returned JSON data in Firebug’s Net tab (or paste into <a href="http://jsonlint.com/">JSONLint</a>) to see structure</li>
</ul>
</div>
<div class="slide">
<h1>Google Maps Developer API</h1>
<p class="description"><a href="https://developers.google.com/maps/documentation/javascript/">https://developers.google.com/maps/documentation/javascript/</a></p>
<style type="text/css">
#map_canvas {
float: right;
width: 50%;
height: 13em;
background-color: fuchsia;
}
</style>
<div id="map_canvas"></div>
<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" charset="utf-8">
var mapOptions = {
center: new google.maps.LatLng(47.65484, -122.307973),
zoom: 18,
mapTypeId: google.maps.MapTypeId.HYBRID
};
var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
</script>
<ul>
<li>Flexible, powerful mapping API with lots of features
<ul>
<li>Dynamically embed a map in your page</li>
<li>Specify zoom, center point, other options</li>
<li>Add markers, paths</li>
<li>Highlight areas, draw shapes</li>
<li>etc.</li>
</ul>
</li>
<li><strong style="font-style: italic">Should</strong> <a href="https://developers.google.com/maps/documentation/javascript/tutorial#api_key">obtain an API key</a>
<ul>
<li>(but it will let you use it a little without one)</li>
</ul>
</li>
<li><a href="https://developers.google.com/maps/documentation/javascript/tutorial">Basic tutorial</a>
<ul>
<li>More detailed tutorials: <a href="https://developers.google.com/maps/documentation/javascript/controls">Controls</a>, <a href="https://developers.google.com/maps/documentation/javascript/overlays">Overlays</a>, <a href="https://developers.google.com/maps/documentation/javascript/layers">Layers</a>, <a href="https://developers.google.com/maps/documentation/javascript/maptypes">Map Types</a></li>
</ul>
</li>
<li><a href="https://developers.google.com/maps/documentation/javascript/tutorial">Examples</a></li>
<li><a href="https://developers.google.com/maps/documentation/javascript/reference">Full API documentation</a></li>
</ul>
</div>
<div class="slide">
<h1>Template: embedded Google map</h1>
<div class="example" style="font-size: 80%">
<pre class="examplecode html">
<head>
...
<em><script src="//maps.googleapis.com/maps/api/js?sensor=false" type="text/javascript" ></script></em>
<style type="text/css">
<span class="comment">/* must give the map container some dimensions for it to show up */</span>
<em>#map_container { width: 50%; height: 10em; }</em>
</style>
...
</head>
<body>
<em><div id="map_container"></div></em>
</pre>
<pre class="examplecode js">
$(document).ready(function() {
<em>initializeMap();</em>
});
function initializeMap() {
<span class="comment">// an object that we'll use to specify options</span>
<em>var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
};</em>
<span class="comment">// the DOM object we're going to put the map into</span>
var mapElement = document.getElementById("map_container");
<span class="comment">// create the map inside mapElement with options specified by mapOptions</span>
var map = <em>new google.maps.Map(mapElement, mapOptions);</em>
}
</pre>
</div>
</div>
<!--#include virtual="../s5/commonbottom.html" -->