A Beginner’s Guide To jQuery-Based JSON API Clients

Advertisement

Are you fascinated by dynamic data? Do you go green with envy when you see tweets pulled magically into websites? Trust me, I’ve been there.

The goal of today’s tutorial is to create a simple Web app for grabbing movie posters from TMDb931. We’ll use jQuery and the user’s input to query a JSON-based API and deal with the returned data appropriately.

I hope to convince you that APIs aren’t scary and that most of the time they can be a developer’s best friend.

APIs Are The Future But, More Importantly, The Present

JSON-based APIs are a hot property on the Web right now. I cannot remember the last time I went onto a blog or portfolio without seeing the owner’s tweets or Facebook friends staring back at me. This interactivity makes the Web an exciting place. The only limit seems to be people’s imagination. As demonstrated by everything from pulled tweets to a self-aware exchange-rates API2, data is currently king, and websites are swapping it freely.

Developers are allowing us to get at their data much more openly now; no longer is everything under lock and key. Websites are proud to have you access their data and, in fact, encourage it. Websites such as TMDb931 and LastFM4 allow you to build entirely separate applications based on the data they’ve spent years accumulating. This openness and receptiveness are fostering an intertwined network of users and their corresponding actions.

screenshot

This article is aimed at people who are competent in HTML and CSS and have basic knowledge of jQuery techniques. We won’t delve deep into advanced JavaScript techniques, but will rather help the beginner who wants to create more complex Web tools.

APIs in a Nutshell

In basic terms, an API enables you to access a website’s data without going near its databases. It gives us a user-friendly way to read and write data to and from a website’s databases.

Sure, Great, But What Code Do I Need?

Like many developers, I bounce merrily between back-end and front-end development, and I am as happy working in PHP as in jQuery. It just depends on which hat I’m wearing that day.

Because this article is mainly about jQuery-based JSON API clients, we’ll focus on client-side code (i.e. jQuery).

When dealing with APIs, and armed with jQuery, one is more likely to encounter JSON.

Player 1: JSON

JSON5 (or JavaScript Object Notation) is a lightweight, easy and popular way to exchange data. jQuery is not the only tool for manipulating and interfacing with JSON; it’s just my and many others’ preferred method.

A lot of the services we use everyday have JSON-based APIs: Twitter, Facebook and Flickr all send back data in JSON format.

A JSON response from an API looks like this:

([{"score":
null,"popularity":
3,"translated":true,"adult":
false,"language":"en","original_name":"The Goonies","name":"The Goonies","alternative_name":"I Goonies",
"movie_type":"movie","id":9340,"imdb_id":"tt0089218",
"url":"http://www.themoviedb.org/movie/9340",
"votes":16,"rating":9.2,"certification":"PG","overview":"A young teenager named Mikey Walsh finds an old treasure map in his father's attic.
Hoping to save their homes from demolition, Mikey and his friends Data Wang, Chunk Cohen, and Mouth Devereaux runs off on a big quest
to find the secret stash of the pirate One-Eyed Willie.","released":"1985-06-07",
"posters":[{"image":{"type":"poster","size":"original","height":1500,"width":1000,
"url":"http://cf1.imgobject.com/posters/76b/4d406d767b9aa15bb500276b/the-goonies-original.jpg",
"id":"4d406d767b9aa15bb500276b"}}],"backdrops":[{"image":{"type":"backdrop","size":"original","height":1080,"width":1920,
"url":"http://cf1.imgobject.com/backdrops/242/4d690e167b9aa13631001242/the-goonies-original.jpg",
"id":"4d690e167b9aa13631001242"}}],"version":3174,"last_modified_at":"2011-09-12 13:19:05"}])

A bit of a mess, right? Compare this to the same JSON viewed in Google Chrome’s developer console:

136

The JSON response is accessible via a jQuery function, allowing us to manipulate, display and, more importantly, style it however we want.

Player 2: jQuery

Personally, I’d pick jQuery over JavaScript any day of the week. jQuery makes things a lot easier for the beginner Web developer who just wants stuff to work right off the bat. I use it every day. If I had to complete the same tasks using native Javascript, my productivity would grind right down. In my opinion, JavaScript is for people who want a deeper understanding of the scripting language and the DOM itself. But for simplicity and ease of use, jQuery is where it’s at.

In essence, jQuery is a JavaScript library, with handy functions like getJSON. This particular function will be the glue that holds our API client together.

The Goal: A jQuery-Based JSON API Client

I recently submitted to An Event Apart7 the Web app that we’re about to go through now. It’s called Front Row8.

The idea of the Web app is to take a movie title inputted by the user, run it through TMDb931’s API, and return the relevant poster. The user could then share it or save it to their computer.

The Web app is split into HTML, CSS and jQuery. We’ll focus on the jQuery, because that’s where the magic happens.

The HTML

Below is the basic structure of the Web app. Nothing special here.

<!DOCTYPE html>
<html>
<head>
   <meta name="author" content="Ben Howdle and Dan Matthew">
   <meta name="description" content="A responsive movie poster grabber">
   <title>Front Row by Ben Howdle</title>
   <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
   <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"></script>
        <!--jQuery, linked from a CDN-->
   <script src="scripts.js"></script>
   <script type="text/javascript" src="http://use.typekit.com/oya4cmx.js"></script>
   <script type="text/javascript">try{Typekit.load();}catch(e){}</script>
   <link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
   <header>
      <h1>Front Row</h1>
   </header>
   <section id="fetch">
      <input type="text" placeholder="Enter a movie title" id="term" />
      <button id="search">Find me a poster</button>
   </section>
   <section id="poster">
   </section>
   <footer>
      <p>Created by <a href="http://twostepmedia.co.uk">Ben Howdle</a></p>
   </footer>
</div>
</body>
</html>

All we’ve got is a bit of Twitter self-indulgence, an input field and a submission button. Done!

The CSS is a bit off topic for this article, so I’ll leave it to you to inspect the elements of interest on the live website.

The jQuery

$(document).ready(function(){

   //This is to remove the validation message if no poster image is present

   $('#term').focus(function(){
      var full = $("#poster").has("img").length ? true : false;
      if(full == false){
         $('#poster').empty();
      }
   });

I like validation messages to disappear when the user starts retyping in an input field. The script below checks whether an image is present (i.e. a movie poster), and if not, empties the container of the validation message once the input field gains focus.

//function definition

   var getPoster = function(){

        //Grab the movie title and store it in a variable

        var film = $('#term').val();

         //Check if the user has entered anything

         if(film == ''){

            //If the input field was empty, display a message

            $('#poster').html("<h2 class='loading'>Ha! We haven't forgotten to validate the form! Please enter something.</h2>");

The reason why we store the main code that retrieves the data in a function will become clear later on (mainly, it’s for DRY programming10).

We then store the value of the input in a variable, so that when we use it again in the code, the jQuery doesn’t have to rescan the DOM.

Basic validation is performed on the input, checking that something has actually been entered in the field.

In an attempt at humor on my part, I display a message warning the user that they haven’t entered anything and asking them to please do so.

} else {

            //They must have entered a value, carry on with API call, first display a loading message to notify the user of activity

            $('#poster').html("<h2 class='loading'>Your poster is on its way!</h2>");

If the input contains a value, we then process the user’s request. Another message is displayed, letting the user know that something is happening.

$.getJSON("http://api.themoviedb.org/2.1/Movie.search/en/json/23afca60ebf72f8d88cdcae2c4f31866/" + film + "?callback=?", function(json) {

               //TMDb is nice enough to return a message if nothing was found, so we can base our if statement on this information

               if (json != "Nothing found."){

                  //Display the poster and a message announcing the result

                     $('#poster').html('<h2 class="loading">Well, gee whiz! We found you a poster, skip!</h2><img id="thePoster" src=' + json[0].posters[0].image.url + ' />');

Here we get to the meat of our API client. We use jQuery’s getJSON11 function, which, by definition, loads “JSON-encoded data from the server using a GET HTTP request.”

We then use the API’s URL, suppled in this case by TMDb12. As with many other APIs, you have to register your application in order to receive a key (a 30-second process). We insert the API key (23afca60ebf72f8d88cdcae2c4f31866) into the URL and pass the user’s movie title into the URL as a search parameter.

One thing to mention is that appending callback=? to the end of the URL enables us to make cross-domain JSON and AJAX calls. Don’t forget this, otherwise the data will be limited to your own domain! This method uses what’s called JSONP (or JSON with padding), which basically allows a script to fetch data from another server on a different domain. To do this, we must specify the callback above when jQuery loads the data. It replaces the ? with our custom function’s name, thereby allowing us to make cross-domain calls with ease.

In the function’s callback, we have put the word json (which holds our retrieved data), but we could have put data or message.

The next check is to see whether any data was returned. TMDb is kind enough to supply us with a message of “Nothing found” when it can’t find anything. So, we’ve based our if statement on this string’s value.

This check is API-specific. Usually if no results are found, we would expand the object to find a property named length, which would tell us how many results were returned. If this happens, the code might look something like this:

if (json.length != 0){

As a side note, before writing even a line of code in the callback function of the JSON call, we should become familiar with the results returned in Chrome’s console or in Firebug. This would tell us exactly what to check for in if statements and, more importantly, what path to take to grab the data we want.

Let’s add console.log(json);, like so:

$.getJSON("http://api.themoviedb.org/2.1/Movie.search/en/json/23afca60ebf72f8d88cdcae2c4f31866/" + film + "?callback=?", function(json) {
         console.log(json);

This will output something like the following in the console of your favorite browser (click the image to see the full size):

136

The last line of this code outputs our poster. We display another message to the user saying that we’ve found a result, and then proceed to show the image.

Let’s spend a moment figuring out how we got to the poster images using the line json[0].posters[0].image.url.

The reason we use json[0] is that — since we want to display only one poster, and knowing how relevant TMDb’s results are — we can gamble on the first result. We then access the posters array like so: json[0].posters[0]. Chrome even tells us that posters is an array, so we know what we’re dealing with. Again, we access the first value of the array, having faith that it will be most relevant. It then tells us that image is an object, so we can access it like so: json[0].posters[0].image. By expanding our object further, we see that image contains a property named url. Jackpot! This contains a direct image link, which we can use in the src attribute of our image element.

} else {

   //If nothing is found, I attempt humor by displaying a Goonies poster and confirming that their search returned no results.

   $.getJSON("http://api.themoviedb.org/2.1/Movie.search/en/json/
23afca60ebf72f8d88cdcae2c4f31866/goonies?callback=?", function(json) {

      $('#poster').html('<h2 class="loading">We're afraid nothing was found for that search. Perhaps you were looking for The Goonies?</h2><img id="thePoster" src=' + json[0].posters[0].image.url + ' />');

   });
}

Having determined that the API has no results for the user, we could display an error message. But this being a movie-related Web app, let’s give the user a preset poster of The Goonies and let them know we couldn’t find anything. We’ll use the exact same src attribute for the image that we used before, this time with goonies hardcoded into the API call’s URL.

});

          }

        return false;
   }

   //Because we've wrapped the JSON code in a function, we can call it on mouse click or on a hit of the Return button while in the input field

   $('#search').click(getPoster);

   $('#term').keyup(function(event){

       if(event.keyCode == 13){

           getPoster();

       }

   });

});

It is now clear why we wrapped our JSON call in a function: doing so allows us to run the function when the user hits the submission button or presses Enter while in the input field.

The Full Code

The HTML

<!DOCTYPE html>
<html>
<head>
   <meta name="author" content="Ben Howdle and Dan Matthew">
   <meta name="description" content="A responsive movie poster grabber">
   <title>Front Row by Ben Howdle</title>
   <meta name="viewport" content="width=device-width, minimum-scale=1.0, maximum-scale=1.0">
   <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.2.min.js"></script>
        <!--jQuery, linked from a CDN-->
   <script src="scripts.js"></script>
   <script type="text/javascript" src="http://use.typekit.com/oya4cmx.js"></script>
   <script type="text/javascript">try{Typekit.load();}catch(e){}</script>
   <link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
   <header>
      <h1>Front Row</h1>
   </header>
   <section id="fetch">
      <input type="text" placeholder="Enter a movie title" id="term" />
      <button id="search">Find me a poster</button>
   </section>
   <section id="poster">
   </section>
   <footer>
      <p>Created by <a href="http://twostepmedia.co.uk">Ben Howdle</a></p>
   </footer>
</div>
</body>
</html>

The jQuery

$(document).ready(function(){

   $('#term').focus(function(){
      var full = $("#poster").has("img").length ? true : false;
      if(full == false){
         $('#poster').empty();
      }
   });

   var getPoster = function(){

        var film = $('#term').val();

         if(film == ''){

            $('#poster').html("<h2 class='loading'>Ha! We haven't forgotten to validate the form! Please enter something.</h2>");

         } else {

            $('#poster').html("<h2 class='loading'>Your poster is on its way!</h2>");

            $.getJSON("http://api.themoviedb.org/2.1/Movie.search/en/json/
23afca60ebf72f8d88cdcae2c4f31866/" + film + "?callback=?", function(json) {
               if (json != "Nothing found."){
                     $('#poster').html('<h2 class="loading">Well, gee whiz! We found you a poster, skip!</h2><img id="thePoster" src=' + json[0].posters[0].image.url + ' />');
                  } else {
                     $.getJSON("http://api.themoviedb.org/2.1/Movie.search/en/json/
23afca60ebf72f8d88cdcae2c4f31866/goonies?callback=?", function(json) {
                        console.log(json);
                        $('#poster').html('<h2 class="loading">We're afraid nothing was found for that search. Perhaps you were looking for The Goonies?</h2><img id="thePoster" src=' + json[0].posters[0].image.url + ' />');
                     });
                  }
             });

          }

        return false;
   }

   $('#search').click(getPoster);
   $('#term').keyup(function(event){
       if(event.keyCode == 13){
           getPoster();
       }
   });

});

Conclusion

That’s it: a handy method of reading data from a remote API with jQuery, and manipulating the JSON output to fit our needs.

Every API is different, and every one returns different results in a different structure — it’s all part of the fun! So, get used to using console.log(), and familiarize yourself with the results set before trying to access it with code or using it in your application.

Start with something practical and entertaining: build a check-in checker with Gowalla’s API; visualize trends with Twitter’s API; or make a face-recognition app with Face.com’s API.

APIs are fun. By definition, the data they bring to the page is dynamic, not static.

If you have any problems with the API we’ve used here or you have any success stories with other APIs, please do leave a comment.

Further Resources

(al)

Footnotes

  1. 1 http://www.themoviedb.org/
  2. 2 http://josscrowcroft.github.com/open-exchange-rates/
  3. 3 http://www.themoviedb.org/
  4. 4 http://www.last.fm/
  5. 5 http://www.json.org/
  6. 6 http://coding.smashingmagazine.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-12-at-22.21.03.png
  7. 7 http://10k.aneventapart.com/
  8. 8 http://10k.aneventapart.com/Entry/Details/550
  9. 9 http://www.themoviedb.org/
  10. 10 http://en.wikipedia.org/wiki/Don't_repeat_yourself
  11. 11 http://api.jquery.com/jQuery.getJSON/
  12. 12 http://api.themoviedb.org/2.1/
  13. 13 http://coding.smashingmagazine.com/wp-content/uploads/2011/09/Screen-Shot-2011-09-12-at-22.21.03.png
  14. 14 http://www.gethifi.com/blog/how-to-use-json-apis-with-jquery
  15. 15 http://richardshepherd.com/how-to-use-jquery-with-a-json-flickr-feed-to-display-photos/
  16. 16 http://www.9lessons.info/2011/02/bing-instant-search-with-jquery-and.html

↑ Back to topShare on Twitter

Ben Howdle is a web developer from Droitwich, UK. He works by day at Wapple.net and by night and weekends as Two Step Media. An insatiable passion for the dynamic web and exciting web applications.

Advertising
  1. 1

    I really enjoyed this tutorial Ben. As a relative beginner there were lots of interesting tidbits for me to take away and expand on.

    PS: what is the name of the script typeface you are using on the site?

    Thanks,
    Dani

    0
  2. 3

    This is a great tutorial… an easy intro to API’s. Thank you!

    0
  3. 4

    This was interesting, but it left me distractingly confused about the key on two points:

    (1) What (if anything) is to prevent key sharing? Can anybody use the key you published in this article (I tried it, and it didn’t work). Was your key revoked after (because) you published it?

    (2) Let’s say you’re supposed to keep your key private. Well, that won’t work, because anyone can view source or similar and see the key used in a web page.

    It just seems like requiring the key is an impediment but doesn’t really provide any authorization.

    1
    • 5

      I think you raise a good point. I think this also carries across to scenarios where people release paid JS plugins, inevitably you can just click view source and it’s right there. But I presume in this occasion, the API is using API keys, not as a strict means of authentication but as a rough handle on how many individual applications are using their API. I have had occasions where certain APIs won’t work without keys (but again, you encounter you’re point with client side key authentication). So, in essence, I’m saying that client side – there’s nothing you can do about people taking your key, but the API you’re using may just be using it as a form of analytics.

      0
      • 6

        API Keys are usually linked to a domain, so if a request with that API Key comes from a different domain, it’s denied.

        0
        • 7

          Keys can restrict usage only for server-side APIs, where the key is not exposed anyway. At issue here is browser-side APIs, where any browser in any domain needs to be able to call the APIs with a key that cannot be hidden. Ben’s answer is quite reasonable.

          0
          • 8

            could malfist be having a point. Could browsers be identifying themselves with the referer header and hence provide a bit of authentication for those that do…

            0
  4. 9

    Thanks man, this is a really great intro to using APIs for web apps and JSON/console.log

    0
  5. 10

    Hi,

    It would be great if you can provide all the files in zipped format.

    Thanks.

    0
  6. 11

    Woow! This is an iteresting toutorial.

    A live demo, would me grat!

    0
  7. 13

    Thank-you!

    Would this be the same for REST API clients?

    0
  8. 15

    It was really great. It was my first time seeing a code not using a form :P Thanks.

    0
  9. 16

    Thank you for the article, Ben. This is a very clear example. I would be very interested in a similar tutorial focused on the back-end using PHP. Is there any chance that something like this is in the works?

    0
  10. 18

    I’ve been really excited about a wordpress plugin called “WordPress JSON API” that makes the content of your wordpress site available via a JSON API. I think this is really powerful as we can start thinking of WordPress as a simple data input and storage tool, and the “theme” for the site can be a JSON API client that is completely separate form the wordpress site.

    0
  11. 20

    “I’d pick jQuery over JavaScript any day of the week”

    Lolwut, is this article for real?

    0
    • 21

      I think it’s clear here that Ben is saying he’d rather use the functionality which jQuery provides in order to make cross-platform development a lot easier, OVER vanilla JS.

      /not a jQuery shill

      No need to be snarky, pal!

      0
    • 22

      I agree – the author implies that jquery is something other than just a JavaScript library and that “native JavaScript” is something else entirely. I know what he means, but I’d not be surprised if beginner was confused.

      0
  12. 23

    Thank you ! Would you do similar tutorials for AJAX with jQuery, everything else with jQuery? Awesome ! Thanks again.

    0
  13. 25

    Thank you :)

    0
  14. 26

    How are you getting around the Origin null issue?

    1
  15. 29

    Awesome ! I done it in ASP as well :)

    0
  16. 30

    Hi,

    Shouldn’t this line $(‘#search’).click(getPoster) become like this: $(‘#search’).click(getPoster());

    Thanks.

    0
  17. 32

    Very neat article on JSON — When I grab the posters — they’re so small.

    0
    • 33

      You’re right! Since writing this article a bug has popped up in the API with small images. I’ll keep on top of it and amend if they find a fix.

      0
  18. 35

    Great stuff! I created something similar using PHP & MySQL a while ago which grabs posters and fanart, a demo can be seen.

    0
  19. 36

    Of course, using a form to submit the query, which would be both semantic and require less jQuery (use a submit handler on the form, which covers enters and clicking) would just be a silly idea ;-)

    0
  20. 37

    Dear Ben,

    A riveting read. Its all become clear now. Thanks.

    Caroline

    0
  21. 38

    Thank you, useful article.

    0
  22. 39

    Neat & precise article on JSON. Smart work Ben.

    0
  23. 40

    This was one of the easiest explanation i’ve seen on json. Thanks it was very helpful!!

    0
  24. 41

    Excellent tutorial.

    How would I grab the other variables such as name and overview and display them on the page?

    0
  25. 42

    great post!
    Ben or anyone know please similar articles like this but with the twitter api ?

    1
  26. 43

    Thanks for the tutorial and very good example.

    0
  27. 44

    dam i learned aaaaaaaalot reading this article, thanks

    0
  28. 45

    Outstanding. You are my hero! Very thorough and succinct. (except for the missing style sheet :))

    0
  29. 46

    Hi Ben,
    Is there anyway you could show how the search is done
    with the the new api 3.0 TMDB. I know this is a late entry
    but 2.1 is going away and I’d like to use this poster finder.
    Really enjoyed the article and learned alot!
    Mark Hubrouck

    0
    • 47

      Hi Mark H!

      I was directed to this tutorial through Thinkful.com’s 3-month front-end web development course(highly recommend it, feel free to email me for more information on that).

      A lot of Googling, StackOverflow questions, and browsing through the new TMDb 3.0 documentation, got a working version of this example using the updated API:

      http://frimmy.github.io/api-test/

      0
  30. 49

    Hi,
    thanks for that great tutorial. I’ve tested it and it works nicely.

    The only thing is that it works well in Firefox an Chrome but with IE 10 the script gets blocked due to a MIME-Type conflict?! Is that a IE bug?

    kind regards, reinhart

    0
  31. 50

    awesome details.. thanks for sharing

    0
  32. 51

    I needed to escape a single quote in this line to get it working

    $(‘#poster’).html(‘We’re afraid nothing was found for that search. Perhaps you were looking for The Goonies?’);

    Other than that an excellent example, just what I was looking for, thanks

    0
  33. 52

    Solid tutorial, I was directed to read as part of learning front end web dev. However, the API reference for TMDb has been updated to ver 3 (2.1 now deprecated).

    Your example/code doesn’t work anymore :( please update?

    0
  34. 53

    Germán Martínez

    January 17, 2014 3:50 pm

    Thank you for the great tutorial.
    The API version has been updated to version 3, so here is a simple example using it:

    $.getJSON(“http://api.themoviedb.org/3/search/movie?api_key=23afca60ebf72f8d88cdcae2c4f31866&query=” + document.getElementById(‘#term’).value + “&callback=?”, function(json) {
    if (json.total_results > 0) {
    content = ”;
    for (i = 0; i < json.total_results; i++) {
    url = json.results[i].poster_path;
    content += '’;
    }
    $(‘#poster’).html(content);
    } else {
    $(‘#poster’).html(“Not found.”);
    }
    });

    Remember that there is a restriction when using this API:
    Maximum 20 simultaneous connections per IP. (http://docs.themoviedb.apiary.io)
    You must be carefull when writing the condition in the loop. Pagination should be used when there are more results than 20.

    Regards from Spain, Germán.

    0
    • 54

      You have some errors in your code, I’m ready the new API changes now and how to build the url to the image is unclear, the docs say something about a configuration object but doesn’t really show you how to use it with the $.getJSON method

      0
  35. 55

    var full = $(“#poster”).has(“img”).length ? true : false;
    if(full == false){
    $(‘#poster’).empty();
    }

    I hope you were barely awake when you wrote that :)

    0
  36. 56

    Almost got this example working on my WP site.
    Just 1 question for me as a beginner, maybe obvious for you:
    The Jquery code: Do i save the code from this page into a .js file and then where to put it? Or am i on the wrong track.
    I know where to put the html code on the webpage, but where to put or insert the jquery code?
    And where to point to that .js file from the html? (replacing existing url’s to .js file?)

    If i get this example working on my site, i can go from there to learn further..

    Thanks,
    Jean Paul

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top