Making API Calls

This tutorial uses some ES6 syntax. You can learn about const here and arrow functions here.

I suggest coding along with this tutorial to get the most out of it. Writing code seems to cement concepts better than copy/pasting other people’s code.

The project we will be making is a simple Pokemon Pokedex, using the Pokeapi V2 API.

One thing I see many people struggle with is making API calls. I had a lot of trouble learning how to do this, and was surprised to find most suggested using jQuery to get the job done. jQuery has a few different tools to make calls with, but I still don’t believe it’s necessary to import a giant library for a tiny task.

What About A Tiny Library?

Now we’re talking. I’m not against using tools outside of vanilla JavaScript, and I do so often. My favorite for making API calls is Axios.

Axios describes itself as a “Promise based HTTP client for the browser and node.js.” Most of these terms beginners should understand, but the difficult concept here is “promise based.” It took me a while to understand promises, so let’s look at what happens when we make an API call and see if we can understand the process a little better.

Before we get to that, though, let’s get some of the code out of the way

For those of you following along in CodePen, please add the axios CDN into the JavaScript area of the settings menu. Any code depicted between <style> tags goes in the box labeled CSS, everything between the <body> tags goes in the html box, and everything in the <script> tags goes in the JavaScript box.

<!DOCTYPE html>
<html>
  <head>
    <meta charset='utf-8'>
    <script src='https://cdnjs.cloudflare.com/ajax/libs/axios/0.15.3/axios.min.js'></script>
    <style>
      html, body {
        margin: 0;
        padding: 0;
      }
      
      .container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        
        width: 100vw;
        min-height: 100vh;
      }
      
      .main {
        width: 450px;
        height: 600px;
        
        background-color: #84152b;
      }
      
      .header {
        margin: 10px;
        
        font-size: 36px;
        font-weight: bold;
        font-family: arial;
        text-align: center;
      }
      
      .pokedex {
        margin: 10px;
        
        height: 520px;
        
        border: 1px solid black;
        background-color: #a39e9f;
      }
    </style>
    <script>

    </script>
  </head>
  <body>
    <div class='container'>
      <div class='main'>
        <div class='header'>Pokeapi Pokedex</div>
        <div class='pokedex'>
          
        </div>
      </div>
    </div>
  </body>
</html>

This gives us just a simple layout that looks like:
A view of the basic layout
As you can see, we’re not aiming for anything fancy here. We just need a place to display the information we get back from our API call.

Promises

API calls, along with many other methods we’ll use in web development, execute asynchronously. JavaScript is a single-threaded application, which means that when we write an algorithm it executes from the top to the bottom, in order. This gives us predictable behavior and makes it easy to understand the order in which our code will execute. Asynchronous (async) tasks get called in order as you’d expect, but they can take some time to complete so the rest of the code gets called while the async task finishes up behind the scenes. This makes sense, because we don’t want to just sit around and wait for an API call to complete before moving on with the rest of our code. Users are impatient.

The difficulty here is that if we don’t wait for the call to complete, the information returned will not be available when the rest of the script executes. This can lead to a lot of frustration for a developer because when we look at it in our code it all makes sense. Make this API call, put the results here, here and here. The problem is the call hasn’t finished before we try to use the results.

This is where the magic that is promises comes into play. In the simplest terms, a promise is like an event listener. We’ve used those before, where we tell the app to listen for a button being clicked or a key to be pressed, and then execute a bit of code in response. Promises work in much the same way, but the event we will be ‘listening’ for here is the API call to complete. Then it will execute a bit of code for us, using the results of the API call.

Let’s go ahead and make a call to our Pokeapi so we can see what kind of information it will return, then we can figure out how we want to display it in our app. I like to use a Chrome app called Postman to play around with APIs, this allows us to easily try out the necessary query strings and API parameters before adding them into our app. I find it’s much easier than making a series of console.log() statements.

Using https://pokeapi.co/api/v2/pokemon as our api url in Postman, we get back an object that looks like this:

A view of our api call in Postman

{
  "count": 811,
  "previous": null,
  "results": [
    {
      "url": "http://pokeapi.co/api/v2/pokemon/1/",
      "name": "bulbasaur"
    },
    {
      "url": "http://pokeapi.co/api/v2/pokemon/2/",
      "name": "ivysaur"
    },
    {
      "url": "http://pokeapi.co/api/v2/pokemon/3/",
      "name": "venusaur"
    },
    {
      "url": "http://pokeapi.co/api/v2/pokemon/4/",
      "name": "charmander"
    },
    {
      "url": "http://pokeapi.co/api/v2/pokemon/5/",
      "name": "charmeleon"
    }
  ...
}

I forgot to update the api url to https instead of http for the images above, but calling https://pokiapi.co/api/v2/pokemon will return the above objects with all of the urls updated to https

We have a key for “count” showing us how many pokemon have been returned, and the meat of our data, a key called “results,” an array of objects representing the first 20 of 811 pokemon this API has returned to us. Arrays are easy to iterate through, so this is good news. Let’s go ahead and add our API call using axios to our app with the following code:

<script>
const container = document.querySelector('.pokedex');

const getPokemonList = () => {
  const url = "https://pokeapi.co/api/v2/pokemon";
  
  axios.get(url)
       .then( (response) => {
          console.log(response);
       })
       .catch( (error) => {
          throw error;
       });
}

getPokemonList();
</script>

This is all it takes to use axios. We pass the API url into axios, and chain onto the initial call with .then(). This is the promise. This tells our app to listen for that API call to complete, and execute whatever code we’ve put in our .then() function. In this case, for right now we are logging the API response to the console so we can see what our response will look like. Also, we have a .catch() statement added to handle any errors our API call may generate.

A view of the dev console after making initial api call

This looks a lot different that what we saw in Postman, it’s a good thing we checked before trying to use the data. It looks like Axios must build a default response object with header information, and the information we want is stored in the key labeled “data.results” Let’s update our script a little and run it again to be sure.

<script>
const container = document.querySelector('.pokedex');

const getPokemonList = () => {
  const url = "https://pokeapi.co/api/v2/pokemon";
  
  axios.get(url)
       .then( (response) => {
          console.log(response.data.results);
       })
       .catch( (error) => {
          throw error;
       });
}

getPokemonList();
</script>

This results in:

An updated view of the api call results logged in the dev console

That’s much better. We’ve trimmed it down to just the array of objects representing the different Pokemon. Now we can loop through this array and add the information to our display. Let’s add some style for our list of pokemon, then we’ll change our axios call to handle the data we receive.

.pokeList {
  width: 90%;
  
  margin: 3px;
  
  font-size: 16px;
  font-weight: bold;
  color: #160105;
  text-align: center;
  
  border: 1px solid black;
  
  cursor: pointer;
}

And our updated axios call:

const getPokemonList = () => {
  const url = "https://pokeapi.co/api/v2/pokemon";
  
  axios.get(url)
       .then( (response) => {
          const data = response.data.results;
    
          data.map( (pokemon) => {
            const div = document.createElement('div');
            const text = document.createTextNode(pokemon.name);
            
            div.appendChild(text);
            div.className += 'pokeList';
            container.appendChild(div);
          });      
       })
       .catch( (error) => {
          throw error;
       });
}

We take the response from our axios call and assign the information stored in the data.results key to a variable named data. Since this information is an array, we can use the method Array.map() to iterate through the array and generate our list of pokemon dynamically. For each item of the array we create a new <div> element, set the text of the element to the name of the pokemon and add our new class we created in the css section. This repeats for every item in the array, giving us the following result:

A view of our pokedex app with api data added

Next week we’ll finish this up by adding pagination to the list, allowing us to view the remaining pokemon in the database, as well as adding functionality which will allow us to view the stats of each pokemon.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s