99 Problems But An API Ain’t One – Thanks to JavaScript

100 Days of Code
100 Days of Code
rando supes

Introduction

So if you havin’ code problems, I feel sorry for you son. I got 99 problems but an API ain’t one…Hopefully @FINALLEVEL sees my humor in that. I do seem to have one problem though. #100DaysOfCode is kicking my butt. Life, man! 

Anywho, I knew javascript was going to be one of the things I got better at. Afterall, it is the language that makes the web interactive. I spent some time catching up on Angela Yu’s Udemy course. You will have seen the name Angela Yu before if you have read some of my previous posts. Be sure to check out the posts about Comrade Cola. Talk about 99 problems.

One of her Node assignments that dealt with Superheroes and Supervillans was inspiration for this. Coupled with a healthy dose of The Boys from Amazon Prime*, I bring you Rando Supes. A quick and easy way to learn about random superheroes.

The Supers

First problem to solve – Where to get a list of superheroes. Luckily the development community is full of amazing people. I found something interesting with https://akabab.github.io/superhero-api/api/. The rest should be a piece of cake. Right? Loads of goodies to pick from in the JSON that is returned. I am only using a small part of what comes back. Here’s a sample record:

{
  "id": 1,
  "name": "A-Bomb",
  "slug": "1-a-bomb",
  "powerstats": {
    "intelligence": 38,
    "strength": 100,
    "speed": 17,
    "durability": 80,
    "power": 24,
    "combat": 64
  },
  "appearance": {
    "gender": "Male",
    "race": "Human",
    "height": [
      "6'8",
      "203 cm"
    ],
    "weight": [
      "980 lb",
      "441 kg"
    ],
    "eyeColor": "Yellow",
    "hairColor": "No Hair"
  },
  "biography": {
    "fullName": "Richard Milhouse Jones",
    "alterEgos": "No alter egos found.",
    "aliases": [
      "Rick Jones"
    ],
    "placeOfBirth": "Scarsdale, Arizona",
    "firstAppearance": "Hulk Vol 2 #2 (April, 2008) (as A-Bomb)",
    "publisher": "Marvel Comics",
    "alignment": "good"
  },
  "work": {
    "occupation": "Musician, adventurer, author; formerly talk show host",
    "base": "-"
  },
  "connections": {
    "groupAffiliation": "Hulk Family; Excelsior (sponsor), Avengers (honorary member); formerly partner of the Hulk, Captain America and Captain Marvel; Teen Brigade; ally of Rom",
    "relatives": "Marlo Chandler-Jones (wife); Polly (aunt); Mrs. Chandler (mother-in-law); Keith Chandler, Ray Chandler, three unidentified others (brothers-in-law); unidentified father (deceased); Jackie Shorr (alleged mother; unconfirmed)"
  },
  "images": {
    "xs": "https://cdn.rawgit.com/akabab/superhero-api/0.2.0/api/images/xs/1-a-bomb.jpg",
    "sm": "https://cdn.rawgit.com/akabab/superhero-api/0.2.0/api/images/sm/1-a-bomb.jpg",
    "md": "https://cdn.rawgit.com/akabab/superhero-api/0.2.0/api/images/md/1-a-bomb.jpg",
    "lg": "https://cdn.rawgit.com/akabab/superhero-api/0.2.0/api/images/lg/1-a-bomb.jpg"
  }
}

Remember to take great care when using APIs. Some, like this one, do not have an auth scheme. It would be very easy to go overboard with requests. I actually had a similar problem whenever a user clicked the Find Another button. I solved one, does that still mean I have 99 problems?

Basic Structure

It is a basic html/js solution. I am using the baked in styles of bootstrap. Separation of concerns is huge in coding. So, I want to make sure we have that here even in this super small example. I used the Bootstrap Pricing example for the base of the html file. 

<!doctype html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
   <meta name="description" content="">
   <title>Rando Supes</title>
   <!-- Bootstrap core CSS -->
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
</head>
<body>
   <div class="mx-auto text-center">
       <h1 class="display-4">Rando Supes</h1>
       <p class="lead">A quick and easy way to learn about random superheroes.</p>
   </div>
   <div class="container col-4">
       <div class="card-deck mb-3 text-center">
           <div class="mb-4">
           </div>
           <div class="card mb-4 shadow-sm">
               <div class="card-header">
                   <h4 id="name" class="my-0 font-weight-normal"></h4>
               </div>
               <div class="card-body">
                   <img id="photo" src="" alt="" />
                   <ul class="list-unstyled mt-3 mb-4">
                       <li><em>First Appearance</em></li>
                       <li id="appearance"></li>
                       <li><em>Occupation</em></li>
                       <li id="occupation"></li>
                   </ul>
                   <button id="btnFindAnother" type="button" class="btn btn-lg btn-block btn-primary">Find Another</button>
               </div>
           </div>
           <div class="mb-4">
           </div>
       </div>
   </div>
   <script src="index.js" charset="utf-8"></script>
</body>
</html>

Clean html. No inline styling or javascript there. 

Async/Await

The javascript is pretty straightforward. I did, however, learn about async and await. Knowledge gains!

var heroes;

const request = async () => {
  const response = await fetch('https://cdn.rawgit.com/akabab/superhero-api/0.2.0/api/all.json');
 heroes = await response.json();
 getNewSupe(heroes);
}

request();

var btnFindAnother = document.querySelector("#btnFindAnother");

btnFindAnother.onclick = function(){
 getNewSupe(heroes);
};

function getNewSupe(superheroList)
{
 var rando = Math.floor(Math.random() * superheroList.length);
 var randoSupe = superheroList[rando];

 var supeName   = randoSupe.name;
 var photo      = randoSupe.images.md;
 var appearance = randoSupe.biography.firstAppearance;
 var occupation = randoSupe.work.occupation;


 document.querySelector("#name").innerHTML = supeName;
 document.querySelector("#photo").src = photo;
 document.querySelector("#appearance").innerHTML = appearance;
 document.querySelector("#occupation").innerHTML = occupation;
}

I must admit, I was excited and confused when I saw examples of using async and await in javascript. Javascript has always been a single threaded beast. Async and Await just didn’t make sense. I was used to the traditional AJAX flow:

  • Create the XMLHttpRequest object in the browser
  • Send a request to a remote server using the XMLHttpRequest object
  • The server processes the request and sends a response back to the browser
  • Process the response with javascript
  • Update the page using javascript

There is a fair amount of coding needed in order to get that to work. Async and await give us much easier constructs to work with. Spin it up and give it a try.

*Something tells me I may be missing out on some nice affiliate swag.

You May Also Like