Retrieving Place Information from Yahoo! with JSONP - Exercise

Contact Us or call 1-877-932-8228
Retrieving Place Information from Yahoo! with JSONP - Exercise

Retrieving Place Information from Yahoo! with JSONP

Duration: 15 to 25 minutes.

In this exercise, you will put to use the JSONP concepts we reviewed previously, using Yahoo! to retrieve information about a user-entered place.

  1. Visit https://developer.yahoo.com/yql/console/; choose "geo.places" from the left-side navigation, under "geo". The Yahoo! developer console gives you the information needed to make a JSONP call to this resource, as well as the structure of the JSON data returned.
    • Note that the example query is 'select * from geo.places where text="sfo"'. Yahoo! returns information about "sfo" - the San Francisco airport in California, US.
    • Check the schema for the returned data by selecting "JSON" (rather than "XML") and clicking the "Test" button: the top-level field is query, which contains an object with field results, which in turn contains a field place.
    • For this query ("sfo") the returned field place contains a number of fields like placeTypeName, whose field content tells us that this is an "Airport", and name, which tells us the full name of "sfo".
    • If we change the query to 'select * from geo.places where text="13066"' - a United States zip code - we see that the query.results.place is now an array: we get results for US zip code "13066" but also for Mexican postal code "130", Brazilian postal code "13066", etc. We'll need to handle this fact - that Yahoo! will sometimes return an array of places and sometimes just a single place.
  2. Open XHR/Exercises/jsonp-yahooquery.html; you'll write the code here:
    • The event-handling code is done for you, getting the user-entered value from the #text input field.
    • Where indicated, create an appropriate URL to send to YQL to get information about the user-entered place.
    • Complete the body of the function displayPlace: test whether the returned result is an array or not (using Array.isArray()) and either iterate over the results or handle the single returned result to set the innerHTML of the #content div.
    • Test your work in a browser.
  3. Test your solution in a browser by visiting XHR/Exercises/jsonp-yahooquery.html

Solution:

XHR/Solutions/jsonp-yahooquery.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>JSONP - Yahoo! Query Language</title>
<script type="text/javascript">
	function displayPlace(data) {
		var content = document.getElementById('content');
		content.innerHTML = '';
		var results = data.query.results.place;
		if (Array.isArray(results)) {
			for(i=0; i<results.length;i++) {
				place = results[i];
				content.innerHTML += '<p>' + place.placeTypeName.content + ': ' + place.name + ' (country: ' + place.country.content + ')</p>';
			}
		} else {
			content.innerHTML += '<p>' + results.placeTypeName.content + ': ' + results.name + ' (country: ' + results.country.content + ')</p>';
		}
	}

	function requestJSONP(url) {
		var script = document.createElement('script');
		script.src = url;
		script.onload = function () {
			this.remove();
		};
		document.head.appendChild(script);
	}

	window.onload = function() {

		var btn = document.getElementById('btn');

		btn.addEventListener('click', function(e) {
			var text = document.getElementById('text').value;
			var script = document.createElement('script');
			var url = "http://query.yahooapis.com/v1/public/yql?format=json&q=select+*+from+geo.places+where+text='" + text + "'&callback=displayPlace";
			requestJSONP(url);
		});
	}
</script>
</head>
<body>
	<input type="text" id="text" placeholder="place">
	<button id="btn">Go</button>
	<div id="content"></div>
</body>
</html>

Code Explanation

We create the URL var url = "http://query.yahooapis.com/v1/public/yql?format=json&q=select+*+from+geo.places+where+text='" + text + "'&callback=displayPlace";, setting the query to send to YQL from the user-entered place name and referencing our callback function displayPlace.

In the displayPlace callback, we first set the contents of div#Content to be empty, so that repeated clicks of the button "wipe out" any previous displayed data.

We then check to see if we get an array returned; if so, we iterate (with a for loop) over the array of returned results, each time appending a new paragraph to div#Content with the type (place.placeTypeName.content) and name (place.name) and country (place.country.content) of the place. If there is no array, we append a single paragraph with the results.

Next