DEV Community

Jackson Williams
Jackson Williams

Posted on

Unlock 650+ Pokémon in 5 Steps: Build Your Dream Index with Vanilla JavaScript

Get ready to catch 'em all with our latest project: building a Pokémon index using the Pokémon API and vanilla JavaScript. To kick things off, let's define our project's goals. We'll create a user-friendly search bar where users can look for their favorite Pokémon, and when they search, the Pokémon's image and stats will be displayed in the results. Although the functionality is straightforward, this project serves as a great foundation for you to customize and add to your portfolio. You can also explore more projects like this on t8tech.com.

Check out the complete version of this project at https://poke-mon.now.sh/.

This project draws inspiration from Chris on Code.

Setting Up the HTML Foundation

Before we dive into the world of JavaScript, we need to lay the groundwork with some HTML. Let's get started.

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Poke.mon</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
  </head>
  <body>
    <form>
      <input type="text" placeholder="Search Pokemon" />
      <input type="submit" value="Search" />
    </form>
    <div class="pokemon-container"></div>
  </body>
</html>

This basic HTML file features an empty div with the class “pokemon-container” and a form with a search bar and a button above it. We'll use the empty div to display our Pokémon data from our JavaScript file.

Adding a Touch of Style

Our webpage looks a bit dull at this point, so let's add some visual flair. We'll create a style.css file and link it to our index.html file.

@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap");

body {
  padding: 30px;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: url("https://i.imgur.com/zwp2EXP.png") center top;
  background-color: #41740e;
  background-repeat: repeat-x;
  background-size: contain;
  font-family: "Press Start 2P";
  position: relative;
}

form {
  background: #ef5350;
  position: fixed;
  display: flex;
  justify-content: center;
  padding: 10px;
  top: 0;
  left: 0;
  right: 0;
}

form input {
  border: none;
  outline: none;
  border-radius: 20px;
  font-size: 18px;
  padding: 12px 20px;
}

form input[type="text"] {
  background: rgba(255, 254, 254, 0.7);
  min-width: 300px;
  max-width: 100%;
}

form input[type="submit"] {
  cursor: pointer;
  margin-left: 8px;
  background: #c62828;
  color: #f0d0d0;
}

.pokemon {
  text-align: center;
}

h2 {
  text-transform: capitalize;
}

.stats {
  font-size: 14px;
}
It will take another post just to discuss the CSS, so let’s move on to the javascript side of things.

Javascript

So let’s code some JavaScript now. We will start with an empty index.js file and discuss what are the steps needed.

  1. Grab the things we need from HTML in index.js.
  2. Take input from the search bar and use that to make API requests.
  3. Make requests to the Pokemon API and fetch the data.
  4. Display the data on the webpage.

Okay, these will be the steps, sounds simple, doesn’t it.

The first step is to get all the div’s, form, etc, from HTML file which is done as follows.

// grab the things we need ----------
const pokemonContainer = document.querySelector(".pokemon-container");
const formEl = document.querySelector("form");
const inputEl = document.querySelector("input[type=text]");

When it comes to identifying elements, we have the option to utilize either the getElementById() or getElementByClass() methods, both of which yield identical outcomes in this particular scenario.

Next, we will attach event listeners to capture the submission event.

// listen for user events -------------
formEl.addEventListener("submit", (e) => {
  e.preventDefault();
  pokemonContainer.innerHTML = "";
  getPokemon(inputEl.value);
});

In this code snippet, we leverage e.preventDefault() to prevent the page from reloading. We then clear the contents of the pokemonContainer div, which may hold previous search results in the future. Finally, we invoke the getPokemon() function, passing the search input as an argument. This function is responsible for handling everything from sending API requests to displaying the results on the page, so let’s explore its intricacies.

The third step involves sending requests to the Pokémon API, accessible at https://pokeapi.co/api/v2/pokemon/, followed by the Pokémon’s unique identifier.

We will create an asynchronous function to achieve this, as demonstrated below:

async function getPokemon(name = "bulbasaur") {
  const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${name}`);
  const pokemon = await res.json();
}

Building a Dynamic Pokémon Interface with Asynchronous Functions

In this illustration, we'll delve into a straightforward asynchronous function known as getPokemon(), which leverages the fetch API to send requests and store the responses in the res variable. The response is then parsed into JSON format using the json() method.

A notable aspect of this function is its capacity to display a default Pokémon prior to initiating a search. This is achieved by adding a name parameter, such as name = bulbasaur, to the function. Furthermore, users can search for specific Pokémon by name.

It's crucial to note that the API only acknowledges lowercase Pokémon names as valid. To accommodate this, you can optionally create a method or function to convert user input to lowercase.

Once we've obtained the Pokémon information and stored it in the res variable, let's examine a traditional API response. Due to the extensive size of the response JSON, we recommend visiting https://pokeapi.co/ to view the raw file.

Now that we have the Pokémon data, let's create a separate div to display the information. We'll start by creating a new div element using document.createElement("div") and assigning it a class of pokemon with classList.add("pokemon").

const pokemonEl = document.createElement("div");
pokemonEl.classList.add("pokemon");

We'll begin by displaying the Pokémon image using .innerHTML and appendChild() to append the data to the web page. Remember that all these operations take place within the getPokemon() function.

pokemonEl.innerHTML = `<div class="info">
<img src="https://pokeres.bastionbot.org/images/pokemon/${pokemon.id}.png" width="200">
<h2>${pokemon.name}</h2>
</div>
`
pokemonContainer.appendChild(pokemonEl);

Presenting Pokémon Details

We leveraged the `innerHTML` property on the `pokemonEl` element, combining it with Template Literals to dynamically inject HTML. This approach enabled us to create a `div` with a class of “info” and populate it with the desired data.

The subsequent step involves isolating the pertinent information within the JSON response and selectively determining what to display in our application. Given the substantial size of the response files, it is crucial to be judicious about the quantity and type of data we wish to showcase.

In terms of the Pokémon image, we can access all of them by simply modifying the `id` in `pokemon.id}.png`. The Pokémon’s name is then displayed using an `

` heading. Finally, we append the `div` to the webpage using `pokemonContainer.appendChild(pokemonEl)`, rendering the information visible to the user.

Delving Deeper into Pokémon Information

At this point, we can successfully display the Pokémon’s name and image. However, there’s a wealth of additional information we can provide, so let’s proceed.

Our next step will be to display the Pokémon’s stats. We can access these stats from the response using `pokemon.stats`. Before we do so, let’s take a closer look at the raw JSON data for the stats. Below, you’ll find the stats for Bulbasaur:

 "stats": [
    {
      "base_stat": 45,
      "effort": 0,
      "stat": {
        "name": "speed",
        "url": "https://pokeapi.co/api/v2/stat/6/"
      }
    },
    {
      "base_stat": 65,
      "effort": 0,
      "stat": {
        "name": "special-defense",
        "url": "https://pokeapi.co/api/v2/stat/5/"
      }
    },
    {
      "base_stat": 65,
      "effort": 1,
      "stat": {
        "name": "special-attack",
        "url": "https://pokeapi.co/api/v2/stat/4/"
      }
    },
    {
      "base_stat": 49,
      "effort": 0,
      "stat": {
        "name": "defense",
        "url": "https://pokeapi.co/api/v2/stat/3/"
      }
    },
    {
      "base_stat": 49,
      "effort": 0,
      "stat": {
        "name": "attack",
        "url": "https://pokeapi.co/api/v2/stat/2/"
      }
    },
    {
      "base_stat": 45,
      "effort": 0,
      "stat": {
        "name": "hp",
        "url": "https://pokeapi.co/api/v2/stat/1/"
      }
    }
  ],

So, now we have to decide what all we want to display. It’s entirely up to you, you can display everything or nothing. Here we will display the name of the stat and its numeric value that is

base_stat

<div class="stats">${pokemon.stats.map((stat) => {

Top comments (0)