5 Problems I Don't Want You to Have While Using APIs

5 Problems I Don't Want You to Have While Using APIs

I'll bet you'll like #4

·

12 min read

APIs (Application Programming Interfaces) are awesome and versatile. They do a great job of taking that leap from front-end web development to the back-end of development. They are also the magic behind a lot of your favorite websites, widgets, and software. Before we get into the nuts and bolts, I want to make it clear that I am far from an advanced API user, and I'm just starting to understand them.

I've come across a few frustrations with APIs that I've used, and I struggled to get them working. Maybe I could see the boatloads of data I wanted to work with, but I couldn't figure out how to access it. Or maybe I just couldn't get the URL to work. Or maybe I wanted more info but didn't know how to get more info. So, I tried to list 5 problems I've had (and solved) in hopes that you won't have the same problems when working with your APIs.

1. https:// is not www.

If you're just a casual web surfer, then you're not going to know the difference between these. Heck, every web browser assumes you don't want to waste time typing in a protocol and it isn't a requirement. Just type in jacobegood.com and you're good to go! 🤪

But if you're a developer, these things matter. Like, A LOT.

There is not much more I can say, but there are huge differences in these lines of code below. I spent enough time trying to find my mistake and commiserating with others to warrant writing about it here.

// this works
const cocktailDBWorks = "https://www.thecocktaildb.com/api/json/v1/1/random.php"

// this doesn't work
const cocktailDB = "www.thecocktaildb.com/api/json/v1/1/random.php"

That one may seem easy, but boy did it get frustrating quickly! So be sure to have the right internet protocol and web address.

3. How do you search?

Not every API will have documentation like this PoetryAPI or this CatPictureAPI. But in general, most of the documentation is easily accessible. It's just about getting into those docs and understanding what they mean.

Let's look at an NBA Stats API. The docs tell us that we should use https://www.balldontlie.io/api/v1/players as our url search.

When we run the code in JavaScript, we get something like this.

fetch('https://www.balldontlie.io/api/v1/players') 
    .then(res => res.json())
    .then(data => console.log(data))
    .catch(err => console.log(err))
// we get something like this
{data: Array(25), meta: {}}
     data: (25) [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, 
           {}, {}, {}, {}, {}]
     meta: {total_pages: 151, current_page: 1, next_page: 2, per_page: 25, total_count: 3757}
           [[Prototype]]: Object

Then we open it up and we can see our data. (I shortened it to only 5 of the original 25)

// open it up and we get this...
data: Array(25)
     0: {id: 14, first_name: 'Ike', height_feet: null, height_inches: null, last_name: 'Anigbogu', }
     1: {id: 25, first_name: 'Ron', height_feet: null, height_inches: null, last_name: 'Baker', }
     2: {id: 47, first_name: 'Jabari', height_feet: null, height_inches: null, last_name: 'Bird', }
     3: {id: 67, first_name: 'MarShon', height_feet: null, height_inches: null, last_name: 'Brooks', }
     4: {id: 71, first_name: 'Lorenzo', height_feet: null, height_inches: null, last_name: 'Brown', }
     5: {id: 90, first_name: 'Omri', height_feet: null, height_inches: null, last_name: 'Casspi', }
     length: 5

If you want to get that first piece of info you'll have to use data.data[0]... why? Because your fetch returned some data and you called it data! data => console.log(data) That data had an object with two parts inside of it. One was an array called data, and another was an object called meta. We want the data's data, so we'll have to call data.data and if we want the first one, we'll call data.data[0] and the second one would be data.data[1] and so on.

This was confusing at first, but after a while you'll be able to recognize the arrays or objects given back to you. I've seen objects, arrays called 'data', arrays called 'results', arrays inside arrays, etc. It is difficult to tell you what you're going to find, and you really just have to play around for a bit to find what works.

Anyway, that's a lot of information! Now, what do I do with it? How am I supposed to use it? Am I supposed to comb through every single item like this to find the one I want? That seems ridiculous.

We need to go back to the docs and find something that we can use. It just so happens that the query parameters tell us we can use search.

search - Used to filter players based on their name. For example, ?search=davis will return players that have 'davis' in their first or last name.

This is becoming more helpful, but we still need to configure a way to search.

If we simply add that ?search=davis to the back of our original URL we can then have a way to search for the data that we want. We'll just need the last name of the NBA player we're looking for.

 // I added the ?search=davis
fetch('https://www.balldontlie.io/api/v1/players?search=davis') 


// you can also add something like this to get user input
const choice = document.querySelector('input').value.trim()

// and pop it into here with template literal notation
fetch(`https://www.balldontlie.io/api/v1/players?search=${choice}`)

If you add a const choice = document.querySelector('input').value.trim() you can now use that choice variable to search too. And voila, now you have info on all the players named Davis. If you want to see the first one of the array, simply add console.log(data[0]). Now you can start to work with the data.

3. API_KEY

Firstly, an API key is just like it sounds. It's a key to access the API. It usually looks like this API_KEY = 'al8sdjan8ueqei336woxns98731kns1'. It helps the website authenticate the application or user. All of the APIs that I used are free, and this lets the API developer know how many calls they are making. Sometimes I've seen them limited to 80 calls a second, 1000 calls a day, and sometimes there are no limits! Wooo! But it's a level of protection and authentication.

Getting an API key usually requires signing up with a valid email address. Once you click through the necessary links, you should get a key. I've had keys emailed to me, pop up instantaneously, searched for 25 minutes to find it... Again, each API is different and you'll just have to do your best to read the docs and find where it'll be.

PRO TIP - Don't share your API_KEY

There are ways to protect your API_KEY like putting it into a .env file, but that's for another day. Don't worry too much if you're just starting out.

API keys are great and terrible simultaneously. Why? Because API keys are something that looks intimidating at first, but in actuality are not that difficult to use. However, it is a process to get the key up and running and make sure that you use it correctly. Each API is different, but you're probably going to be asked to pop it into the URL you're using. Initially, you should store the API_KEY in a variable so you can use it without copying/pasting.

`API_KEY = 'al8sdjan8ueqei336woxns98731kns1'` 
// storing an API_KEY like this is not recommended but is just for the purpose of this blog

After you have it stored, then you can simply pop your API_KEY into the correct place of the URL.

API_KEY = 'al8sdjan8ueqei336woxns98731kns1'
base_url = `https://compare-flight-prices.p.rapidapi.com/${API_KEY}/GetPrices.aspx`

 fetch(base_url)
      .then(res => res.json()) // parse response as JSON
      .then(data => {
        console.log(data)

And that's it. Keys are sometimes added in the middle of the URL, and other times added at the end.

4. Populating a list

This should deserve its own blog, but I'm going to try to do it here. It's a bit more complicated than it needs to be, but hopefully, you can follow along.

I'll be using the Metropolitan Museum of Art's API.

Populating a webpage with loads of pictures/data is something that I wanted to jump into after figuring out how to get the information from an API. After I felt comfortable getting data, I wanted to make sure that I could use the data seamlessly on a webpage instead of calling the API for every single picture, name, description, or data point that I needed. So, how would you populate a list of items?

First, this is what my HTML page looks like. There is a bit more but this is a general idea and all we really need to know. There is a button, a div, and a ul.

<button id='btn' type="button" name="button">Get Pics</button>

        <div id="ul-div">
            <ul id="ul-list">
                 <!--- I AM EMPTY  --- >
            </ul>
        </div>

After that is in your index.html, you'll need to make sure to find an appropriate API. I chose a mildly difficult one because I like to torture myself. Also, it'll highlight some other things that don't need too much explanation. I'll first have to call the hasImageRequest to the Met Museum API to see if they actually have an image. Some didn't, and that was frustrating. It goes back to #3 above with How to search. So, be wary, sometimes APIs have the information you want but you have to go find it.

To simplify things, I left out using the button and just put in Auguste Renoir as a search name.

const hasImageRequest =  'https://collectionapi.metmuseum.org/public/collection/v1/search?hasImages=true&q=Auguste Renoir'

  fetch(hasImageRequest)
      .then(res => res.json()) 
      .then(data => {
        console.log(data)

        // getting 10 responses that HAVE IMAGES and putting them into an array
        let firstTen = []
        for (let i=0; i<10; i++) {
          firstTen.push(data.objectIDs[i])
        }

So, what I'm doing is adding a data.objectID to an array. The reason I am doing this is that I'll have to use that data.objectID to make the next call for the picture. There may be other ways to do this, but I found that this would be effective enough for my purpose.

After I get the first 10 IDs into an array, I'll have to loop through that array to make a call for each image I want. Sometimes you'll have to do this, other times the API might have a list already for you. Like this JokesAPI actually lets you choose the number of jokes that you want. https://v2.jokeapi.dev/joke/Any?amount=10. That's awesome, but it's not always that easy.

To loop through thins, I like basic for (let i = 0; i<10; i++) loops, but you could also use a forEach() if you're more comfortable with that.

Here's a quick highlight. I get the length of the firstTen array and loop through that while appending the firstTen[i] onto my metroBaseUrl. This will return a new object each time (10 times total). From there I will grab the data.primaryImageSmall URL I need and add it to my <img src="" />.

const metroArtBaseUrl = 'https://collectionapi.metmuseum.org/public/collection/v1/objects/'

        for (let i=0; i<firstTen.length; i++) {
          fetch(metroArtBaseUrl+firstTen[i])
          .then(res => res.json())
          .then(data => {
            console.log(data)
            let ele = document.createElement('li')
            ele.innerHTML = `
              <img src="${data.primaryImageSmall}" 
                     id="${data.primaryImageSmall}" 
              />
            `
            document.querySelector("#ul-list").appendChild(ele)

I'm also creating a li element and inside that, I will add the innerHTML with an image source. Others may want to create another img element, but I like using innerHTML because it's easier for me.

Finally, I'll append that element to the ul-list that is already set up over on index.html. Another caveat (too many?) is that the ul-list style will persist even if nothing is inside it. My box shadow and outline in CSS had to be edited, but that wasn't too big a deal for me. For my purpose, I don't really care about that, but you should be aware that sometimes it may affect the design of your site.

Okay, I think that's about everything. When it's all together, the JS code should look like this.

const hasImageRequest =  'https://collectionapi.metmuseum.org/public/collection/v1/search?hasImages=true&q=Auguste Renoir'

  // first fetch here! 
  fetch(hasImageRequest)
      .then(res => res.json()) // parse response as JSON
      .then(data => {
        console.log(data)

        // getting 10 responses that HAVE IMAGES and putting them into an array
        let firstTen = []
        for (let i=0; i<10; i++) {
          firstTen.push(data.objectIDs[i])
        }

        // this is the base url I will use to get the images
        const metroArtBaseUrl = 'https://collectionapi.metmuseum.org/public/collection/v1/objects/'

        for (let i=0; i<firstTen.length; i++) {
         // second fetch here using those 10 objectIDs! probably should be another function :)
          fetch(metroArtBaseUrl+firstTen[i])
          .then(res => res.json())
          .then(data => {
            console.log(data)
            let ele = document.createElement('li')
            ele.innerHTML = `
              <img src="${data.primaryImageSmall}" 
                     id="${data.primaryImageSmall}" 
              />
            `
            document.querySelector("#ul-list").appendChild(ele)

          })
          .catch(err => {
            console.log('error: ', err)
          })
        }          
      })
      .catch(err => {
          console.log(`error ${err}`)
      });
}

I'd like to point out that I called 2 fetch functions, one inside the other. You probably should break these into two separate functions and that's (I assume) industry best practice. But in my coding experience, this works fine for now. In any case, I do this initially to help me really understand what's happening with the code. Just be aware though that some people may not like this and you'll definitely have to learn to refactor it later.

Now, you should have a populated list with 10 different images from the MET API! Well done :)

5. Which API should I use?

This is maybe the easiest solution to all the problems I faced. I'm not going to sugarcoat it. If you're a new developer and you want to get better, you're going to have to practice using APIs, so just choose something and start building! Seriously, there are loads of resourceshere, here, and here! And I haven't even mentioned the company called RapidAPI!

I know I argued in a blog before that finding an appropriate project can and should be time-consuming, but now I'm playing devil's advocate and saying that you need to just start. You're practicing! Your project is not going to be the next Twitter, Facebook, Youtube, or IMDB. Why? Because they've already been made and the internet needs something new. Sorry, but now is time to practice not build the next big thing, that'll come later!

Also, as a teacher, I know that it's important for students to simply fail, learn, and try again. It is also helpful to see an "example" and then CLONE that example. Examples give you an outline, a million-dollar idea, and everything you need. Now, it's time for you to see if you can do it too! I love cloning work because I'm not a great designer. I'm studying to be one, but right now I want to become better at programming. So take that idea and try it out yourself. You'll learn so much!

When you get more confident, of course, you should try to design something and write your own ideas, but don't let procrastination or the affluence of free APIs stop you from CREATING something. Seriously, just start... please?!

That's it for now. If you liked what you read, please follow me on Twitter, connect with me on LinkedIn or follow me here on Hashnode.

Did you find this article valuable?

Support Jacob Good by becoming a sponsor. Any amount is appreciated!