DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack

Trending

  • What’s Got Me Interested in OpenTelemetry—And Pursuing Certification
  • Developers Beware: Slopsquatting and Vibe Coding Can Increase Risk of AI-Powered Attacks
  • Proactive Security in Distributed Systems: A Developer’s Approach
  • Tired of Spring Overhead? Try Dropwizard for Your Next Java Microservice
  1. DZone
  2. Data Engineering
  3. Data
  4. Building Pokemon Index in Vanilla JS

Building Pokemon Index in Vanilla JS

By 
Ashutosh Singh user avatar
Ashutosh Singh
DZone Core CORE ·
May. 29, 20 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
6.7K Views

Join the DZone community and get the full member experience.

Join For Free

In this post, we are going to build a Pokemon index using Pokemon API in plain Javascript. First, let’s discuss what this project is about. There will be a search bar where users can come and search for a Pokemon, and after the search, Pokemon with its image and stats, as a result, will be shown. So, the functionality is pretty basic but you using this project as a base can tweak and make your own version of this project and add it to your portfolio.

The full version is deployed at https://poke-mon.now.sh/.

This project is inspired by Chris on Code.


HTML Structure

Before we dive into JavaScript, we first have to code some HTML, just to structure our project. So let’s do that

HTML
xxxxxxxxxx
1
15
 
1
<!DOCTYPE html>
2
<html lang="en">
3
  <head>
4
    <title>Poke.mon</title>
5
    <meta charset="UTF-8" />
6
    <meta name="viewport" content="width=device-width, initial-scale=1" />
7
  </head>
8
  <body>
9
    <form>
10
      <input type="text" placeholder="Search Pokemon" />
11
      <input type="submit" value="Search" />
12
    </form>
13
    <div class="pokemon-container"></div>
14
  </body>
15
</html>


It's just a simple HTML file with an empty div with class pokemon-container, and above it is a form with a search bar and a button, Nothing fancy. We will use the empty div to display our Pokemon data from our JavaScript file.

Some Styling

The webpage looks too plain as of now so let’s just style it a bit. Let’s create a style.css file and link it to our index.html

CSS
xxxxxxxxxx
1
60
 
1
@import url("https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap");
2
3
body {
4
  padding: 30px;
5
  min-height: 100vh;
6
  display: flex;
7
  flex-direction: column;
8
  align-items: center;
9
  justify-content: center;
10
  background: url("https://i.imgur.com/zwp2EXP.png") center top;
11
  background-color: #41740e;
12
  background-repeat: repeat-x;
13
  background-size: contain;
14
  font-family: "Press Start 2P";
15
  position: relative;
16
}
17
18
form {
19
  background: #ef5350;
20
  position: fixed;
21
  display: flex;
22
  justify-content: center;
23
  padding: 10px;
24
  top: 0;
25
  left: 0;
26
  right: 0;
27
}
28
29
form input {
30
  border: none;
31
  outline: none;
32
  border-radius: 20px;
33
  font-size: 18px;
34
  padding: 12px 20px;
35
}
36
37
form input[type="text"] {
38
  background: rgba(255, 254, 254, 0.7);
39
  min-width: 300px;
40
  max-width: 100%;
41
}
42
43
form input[type="submit"] {
44
  cursor: pointer;
45
  margin-left: 8px;
46
  background: #c62828;
47
  color: #f0d0d0;
48
}
49
50
.pokemon {
51
  text-align: center;
52
}
53
54
h2 {
55
  text-transform: capitalize;
56
}
57
58
.stats {
59
  font-size: 14px;
60
}

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.

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


We can use getElementById() or getElementByClass() here it makes no difference.

Now, we will add event listeners to listen to the submit command

JavaScript
xxxxxxxxxx
1
 
1
// listen for user events -------------
2
formEl.addEventListener("submit", (e) => {
3
    e.preventDefault();
4
    pokemonContainer.innerHTML = "";
5
    getPokemon(inputEl.value);
6
});


Here, we use e.preventDefault() to stop the page from refreshing. Then, we clear the div with class pokemonContainer although it is empty for now. In the future, we may search multiple times, and each time we would have to clear the div which is still holding the previous information. Next is getPokemon() method in which the search input is passed as an argument. This function will do everything from making requests to the API and to displaying it to the page. So let’s discuss this function.

The third step is to make requests to the Pokemon API, which is: https://pokeapi.co/api/v2/pokemon/+ id

We will be making an async function here as follows

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


This is a simple async function, named getPokemon() in which API requests are made using fetch and stored in res variable which is further converted to JSON using json(). In addition to users being able to search for the Pokemon, by adding name = bulbasaur in parameters, we can show a default Pokemon, even before a search is initiated. 

Another thing that I want to discuss here is that only lowercase Pokemon names are considered valid, so keep that in mind when making requests. Optionally, you can add a method or function to convert user input into lower case.

Now that we have stored the Pokemon information into res, let’s take a look at a traditional response of the API.

Since the response JSON is too big to show here, you can go to https://pokeapi.co/ and view the raw file.

We have the information on the Pokemon so let’s show it, we will start by creating a different div for showing the information, as follows:

JavaScript
xxxxxxxxxx
1
 
1
const pokemonEl = document.createElement("div");
2
pokemonEl.classList.add("pokemon");


We created a div element using document.createElement() and then gave it a class of pokemon using classList.add().

We will first show the image of the Pokemon. For that we will use .innerHTML and appendChild() to put the information or data on the web page.

And remember we are doing all this inside getPokemon() function.

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


We used the innerHTML on pokemonEl and then used Template Literals to add HTML. We added a div with class info, and basically, the next steps are just figuring out where in the JSON are the information that you need and want to show on your application, the response files are large so you have to be selective as to how much information and what information do you want to show. 

As for the image of the pokemon, you can access all of them just by changing the id in pokemon.id}.png. Then we display the name of the Pokemon in <h2>. The last step in this is to append the div on to the webpage to actually show the information which is done using pokemonContainer.appendChild(pokemonEl)

By now, we can show the name and image of the Pokemon, but there are tons of information we can display, so let’s go on with.

We will first display stats of the Pokemon, by accessing the stats from the response using pokemon.stats but first look at the raw JSON of stats. Below are the stats of Bulbasaur:

JSON
xxxxxxxxxx
1
50
 
1
 "stats": [
2
    {
3
      "base_stat": 45,
4
      "effort": 0,
5
      "stat": {
6
        "name": "speed",
7
        "url": "https://pokeapi.co/api/v2/stat/6/"
8
      }
9
    },
10
    {
11
      "base_stat": 65,
12
      "effort": 0,
13
      "stat": {
14
        "name": "special-defense",
15
        "url": "https://pokeapi.co/api/v2/stat/5/"
16
      }
17
    },
18
    {
19
      "base_stat": 65,
20
      "effort": 1,
21
      "stat": {
22
        "name": "special-attack",
23
        "url": "https://pokeapi.co/api/v2/stat/4/"
24
      }
25
    },
26
    {
27
      "base_stat": 49,
28
      "effort": 0,
29
      "stat": {
30
        "name": "defense",
31
        "url": "https://pokeapi.co/api/v2/stat/3/"
32
      }
33
    },
34
    {
35
      "base_stat": 49,
36
      "effort": 0,
37
      "stat": {
38
        "name": "attack",
39
        "url": "https://pokeapi.co/api/v2/stat/2/"
40
      }
41
    },
42
    {
43
      "base_stat": 45,
44
      "effort": 0,
45
      "stat": {
46
        "name": "hp",
47
        "url": "https://pokeapi.co/api/v2/stat/1/"
48
      }
49
    }
50
  ],

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
JavaScript
xxxxxxxxxx
1
 
1
<div class="stats">${pokemon.stats.map((stat) => {
2
    return `<p>${stat.stat.name}: ${stat.base_stat}</p>`;
3
}).join("")}</div>


We made another div inside innerHTML and gave it a class stats.

As you can see above, in the raw JSON, the stats actually contains an array of objects, so to access that and to just display the name and base_stat. For that, we use map() method on the stat array, what map() does that it takes every element of the array one by one in this case objects and creates a new array with the results of calling a function for every array element. 

Or in simple words, the map() method calls the provided function once for each element in an array, in order. That function, in this case, is a callback that takes stat as an argument and returns a paragraph <p> that holds the name and base_stat using Template Literals. The whole array is later converted into a string using join() method.

Now, let’s take a look at the output of the above code,

JavaScript
xxxxxxxxxx
1
 
1
speed: 45
2
special-defense: 65
3
special-attack: 65
4
defense: 49
5
attack: 49
6
hp: 45
7
 


Before proceeding further, let’s show different information using the same logic as above, let’s show the abilities of the Pokemon, this time there is no numeric value to be shown, other than that the code remains almost same.

JavaScript
xxxxxxxxxx
1
 
1
<div class="abilities">${pokemon.abilities.map((ability) => {
2
    return `<p>${ability.ability.name}</p>`;
3
})
4
.join("")}
5
<div>


The output of the above will be as follows,

JavaScript
xxxxxxxxxx
1
 
1
chlorophyll
2
overgrow

You can also show moves of the Pokemon, as follows:
JavaScript
xxxxxxxxxx
1
 
1
<div class="moves">
2
${pokemon.moves.map((move) => {
3
    return `${move.move.name}  `;
4
})
5
.join("")}
6
<div>


The output of the above is shown below

JavaScript
xxxxxxxxxx
1
 
1
razor-wind swords-dance cut bind vine-whip headbutt tackle body-slam take-down double-edge growl strength mega-drain 
2
leech-seed growth razor-leaf solar-beam poison-powder sleep-powder petal-dance string-shot toxic rage mimic double-team 
3
defense-curl light-screen reflect bide sludge skull-bash amnesia flash rest substitute snore curse protect sludge-bomb mud-slap
4
giga-drain endure charm swagger fury-cutter attract sleep-talk return frustration safeguard sweet-scent synthesis hidden-power 
5
sunny-day rock-smash facade nature-power ingrain knock-off secret-power grass-whistle bullet-seed magical-leaf natural-gift 
6
worry-seed seed-bomb energy-ball leaf-storm power-whip captivate grass-knot venoshock round echoed-voice grass-pledge work-up 
7
grassy-terrain confide

Complete index.js file is as follows. As you can see here,  getPokemon()

JavaScript
xxxxxxxxxx
1
56
 
1
// grab the things we need ----------
2
const pokemonContainer = document.querySelector(".pokemon-container");
3
const formEl = document.querySelector("form");
4
const inputEl = document.querySelector("input[type=text]");
5
6
// listen for user events -------------
7
formEl.addEventListener("submit", (e) => {
8
  e.preventDefault();
9
  pokemonContainer.innerHTML = "";
10
  getPokemon(inputEl.value);
11
});
12
13
// define our functions/actions ------------
14
async function getPokemon(name = "bulbasaur") {
15
  const res = await fetch(`https://pokeapi.co/api/v2/pokemon/${name}`);
16
  const pokemon = await res.json();
17
18
  const pokemonEl = document.createElement("div");
19
  pokemonEl.classList.add("pokemon");
20
21
  pokemonEl.innerHTML = `
22
    <div class="info">
23
      <img src="https://pokeres.bastionbot.org/images/pokemon/${
24
        pokemon.id
25
      }.png" width="200">
26
<h2>${pokemon.name}</h2>
27
    </div>
28
    <div class="stats">
29
      ${pokemon.stats
30
        .map((stat) => {
31
          return `<p>${stat.stat.name}: ${stat.base_stat}</p>`;
32
        })
33
        .join("")}
34
    </div>
35
    <div class="abilities">
36
    ${pokemon.abilities
37
      .map((ability) => {
38
        return `<p>${ability.ability.name}</p>`;
39
      })
40
      .join("")}
41
    <div>
42
    
43
    <div class="moves">
44
    ${pokemon.moves
45
      .map((move) => {
46
        return `${move.move.name}  `;
47
      })
48
      .join("")}
49
    <div>
50
  `;
51
52
  pokemonContainer.appendChild(pokemonEl);
53
}
54
55
// run things ----------------
56
getPokemon();

is also called in the end, just to show the default Pokemon, which is Bulbasaur.

GitHub Repository

lelouchB/poke.mon

Deployed at https://poke-mon.now.sh/

Poke.mon

poke-mon.now.sh


Your Versions

Following are a few ideas that can be done to this existing project to make it more interesting, you can use these to make your own version of the project

  1. Screenshot Feature

You can add a screenshot feature in this project so that users can take a screenshot of the pokemon information.

2. Displaying additional information

As you have seen in the raw JSON, many of the moves and abilities contain a URL that has additional in-depth information about moves or abilities. You can show that information on the web page.

3. Fight

A really amazing option, user can search and select two pokemon, images displaying at opposite sides of the webpages, and then click on a fight button, then they will come close suing some animations or CSS, and then finally the pokemon with higher stats wins and a WIN message is shown.

JavaScript Statistics

Published at DZone with permission of Ashutosh Singh, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!