Tutorial: An Easter egg hunt with “places”

14 Apr 2017 by Harry Wood

Back in December we introduced our new endpoint called “places”. In this tutorial we will create a web page with javascript to do a call to that. Since it allows us to do a textual search, and since it’s Easter…. let’s search for “Eggs”

This tutorial is more about web development, and less about TransportAPI, but let’s start with the TransportAPI bit:

The URL

What is the URL we need to call?

A places call (documented here) starts with https://transportapi.com/v3/uk/places.json. We want to do a textual search for “Eggs”, so we add the parameter ?query=Eggs. We could also specify a ‘type’ parameter, but we’re going to leave that out so that we get a mixtures of places types returned. Finally add your app_id and app_key parameters (Don’t have an app_id and app_key? Head to developer.transportapi.com to get set up with that). Our full TransportAPI URL looks like this:
https://transportapi.com/v3/uk/places.json?query=Eggs&app_id=...&app_key=...

We can try that out in a browser (Try it now!) :

We have data! If you install a browser plugin such as Chrome’s ‘JSON Formatter” extension, then you might even see nicely formatted data, but it’s time to build a website which displays this.

A basic HTML page

Start with some basic HTML, and a dash of javascript.

<html>
  <head>
  <title>An Easter egg hunt with TransportAPI</title>
  <script>
     function init() {
       alert('Happy Easter');
     }
  </script>
  </head>

  <body onLoad="init();">
    Let's go on an egg hunt
  </body>
</html>

Put that in a file and open it with your browser.

Loading jQuery

jQuery is a library offering various javascript features. We’re going to be using the ajax function in particular, so let’s bring in jQuery. For now we’ll just embed it via their CDN rather than downloading it.

Add this script tag to the HTML head. Add it above the other ‘script’ tag:

<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>

An ajax call to TransportAPI

Now we’re ready to do an ‘ajax’ call. In the ‘init’ function delete that test ‘alert’, and replace it with this:

    var url = 'https://transportapi.com/v3/uk/places.json?query=Eggs&app_id=...&app_key=...';
    $.ajax({
      dataType: "text",
      url: url
    }).done(function(data) {
      console.log(data);
      $('#egglist').html("Data on the web! " + data);
    });

Change the first line where ‘url’ is set, to include your app_id and app_key (the same URL you tested before)

jQuery functions have the $ prefix. Here we’re calling the function $.ajax which will trigger a request to TransportAPI. To process the response data we provide callback logic in the .done section. Everything in the .done function is executed a little later on, when the request from TransportAPI comes back (it’s asynchronous). So far we’ve got just two lines in there:

The first line console.log(data); tells the browser to log the response data to the javascript console. Try it in your browser now. Open the javascript console (how?) and then refresh the page. You should see response data written to the console looking something like this:

This proves we’re getting data into our javascript code. The javascript console is also the first place to check for errors or warnings when troubleshooting.

The second line $('#egglist').html("Data on the web! " + data); …is not working yet. It tells the browser to look for an ‘egglist’ element on the page, and fill it with data. So we need to add this in the body section (down the bottom):

<div id='egglist'>Loading eggs...</div>

Add this after the line “Let’s go on an egg hunt”

Refresh. Now, for the first time, you should see something interesting happening on the web page itself. Interesting but still rather raw unformatted data.

Listing the eggs from the places API result

Change dataType: "text", to dataType: "json",.

TransportAPI is returning json formatted data. This should be parsed into javascript data structures automatically, so that the search results from the places API are now represented as an array to be looped through.

Change the code in the .done section to introduce data processing logic:

      console.log(data);
      $('#egglist').html('<h3>Eggs:</h3>');
      for (var place of data.member) {
        $('#egglist').append('<div>Egg: ' + place + '</div>');
      }

Refresh, and you should see we’re starting to list out the places (search matches). There are 30 or so elements in the data.member array, but the browser will render the place variable as “[object Object]”. That’s because it’s a data structure containing several fields of information about each of the search matches.

Fix this by changing place to place.name

Refresh, and our easter egg hunt is starting to get somewhere! You should see the names of places featuring the word ‘Eggs’.

Using more fields of the response

One of the fields is called ‘name’. A places search result also has ‘type’, ‘description’, ‘latitude’, ‘longitude’, among others. How do we know this? We can explore the data itself with the javascript console, to look inside ‘members’ and see what each of the search results looks like. Or we can read the API docs! The “schema” section describes the fields and structures making up responses from the API.

We can use these fields to build up our HTML display however we please. Feel free to experiment, but here’s an example where we’re displaying the type, and making use of the latitude and longitude fields to make a link to a map:

      for (var place of data.member) {
        var eggHTML = '<div class="egg">' +
                      '<a href="https://www.openstreetmap.org/?mlat=' + place.latitude + '&mlon=' + place.longitude + '&zoom=14">' +
                      place.name + ' (' + place.type + ')' +
                      '</a>' + 
                      '</div>';
        $('#egglist').append(eggHTML);
      }

We’re generating HTML as a string within the javascript. Pay close attention to single quotes versus double quotes. You might prefer appending jQuery element objects, or some more sophisticated templating approach, but for a quick demo this works.

Speaking of which, it’s worth pointing out that we should really add a .fail error handler alongside our .done function and also check for an ‘error’ field in the response. We’ll leave that as exercise for you to figure out. For a quick demo this works.

Some CSS

Just to prove we can display this data any way we want, let’s add a final Easter flourish.

Add the following style just before </head>:

<style>
.egg {
  float:left;
  -webkit-box-sizing: content-box;
  -moz-box-sizing: content-box;
  box-sizing: content-box;
  width: 120px;
  height: 90px;
  padding-top:50;
  border: none;
  font-size: 0.8em;
  text-align:center;
  -webkit-border-radius: 50% / 60% 60% 40% 40%;
  border-radius: 50% / 60% 60% 40% 40%;
  color: rgba(0,0,0,1);
  background: RED;
}
.egg a { color: YELLOW; }
</style>

Refresh to see how it looks!

Yes. It turns out you can make an egg shape using CSS. We all learned something new today!

See the finished website running. You can also use this to cheat and do ‘view source’, to see how your final file should have looked.

Happy Easter from TransportAPI!

Transport API