Build a Pokémon Search App Project - Build a Pokémon Search App

Tell us what’s happening:

I believe my code is working fine and am really proud of this project, but tests #14 and sometimes #21 are not passing. Both having to do with the alert message if an invalid name or id is given.

Your code so far

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Pokemon Search App</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <main>
      <h1>Pokémon Search App</h1>
      <div class="container">
        <p>Search for Pokémon Name or ID:</p>
        <input id="search-input" required />
        <button id="search-button">Search</button>
        <div class="name-container" id="name-container">
          <div class="title">
            <span id="pokemon-name"></span>
            <span id="pokemon-id"></span>
          </div>
          <div class="size">
            <span id="weight"></span>
            <span id="height"></span>
          </div>
          <div class="types" id="types"></div>
          <div id="image"></div>
        </div>
        <div class="table-wrapper">
          <table>
            <thead>
              <tr>
                <th >Base</th>
                <th>Stats</th>
              </tr>
            </thead>
            <tr>
              <td>HP:</td>
              <td id="hp"></td>
            </tr>
            <tr>
              <td>Attack:</td>
              <td id="attack"></td>
            </tr>
            <tr>
              <td>Defense:</td>
              <td id="defense"></td>
            </tr>
            <tr>
              <td>Sp. Attack:</td>
              <td id="special-attack"></td>
            </tr>
            <tr>
              <td>Sp. Defense:</td>
              <td id="special-defense"></td>
            </tr>
            <tr>
              <td>Speed:</td>
              <td id="speed"></td>
            </tr>
          </table>
      </div>
    </main>
  <script src="./script.js"></script>
  </body>
</html>

h1, p, .container, td {text-align: center}

p {font-weight: bold;
font-size: 20px}

table {margin-left: auto;
margin-right: auto}

.container {
  width: 80%;
  background-color: #cc0000;
  margin-left: auto;
  margin-right: auto;
  padding: 10px 10px;
  border-radius: 10px;
  border: solid 2px #3B4CCA
}

.name-container {width: 70%;
height: 200px;
background-color: white;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
margin-bottom: 10px;
border-radius: 10px;
padding: 5px;
border: solid 2px #3B4CCA}

img {width: 50%}

.table-wrapper {width: 70%;
margin-left: auto;
margin-right: auto;
margin-top: 10px;
margin-bottom: 10px;}

td {background-color: #FFDE00;
width: 100%;}

table {font-size: 20px;
}

.title {font-weight: bold;
text-align: left}

.size, .types {text-align: left;
margin-bottom: 3px}

.poison {background-color: #A33EA1;
border-radius: 2px;
padding: 2px}
.grass {background-color: #7AC74C;
border-radius: 2px;
padding: 2px}
.normal {background-color: #A8A77A;
border-radius: 2px;
padding: 2px}
.fire {background-color: #EE8130;
border-radius: 2px;
padding: 2px}
.water {background-color: #6390F0;
border-radius: 2px;
padding: 2px}
.electric {background-color: #F7D02C;
border-radius: 2px;
padding: 2px}
.ice {background-color: #96D9D6;
border-radius: 2px;
padding: 2px}
.fighting {background-color: #C22E28;
border-radius: 2px;
padding: 2px}
.ground {background-color: #E2BF65;
border-radius: 2px;
padding: 2px}
.flying {background-color:#A98FF3;
border-radius: 2px;
padding: 2px}
.psychic {background-color: #F95587;
border-radius: 2px;
padding: 2px}
.bug {background-color: #A6B91A;
border-radius: 2px;
padding: 2px}
.rock {background-color: #B6A136;
border-radius: 2px;
padding: 2px}
.ghost {background-color: #735797;
border-radius: 2px;
padding: 2px}
.dragon {background-color: #6F35FC;
border-radius: 2px;
padding: 2px}
.dark {background-color:#705746;
color: white;
border-radius: 2px;
padding: 2px}
.steel {background-color: #B7B7CE;
border-radius: 2px;
padding: 2px}
.fairy {background-color:#D685AD;
border-radius: 2px;
padding: 2px}

const input = document.getElementById("search-input");
const button = document.getElementById("search-button");
const pokeName = document.getElementById("pokemon-name");
const pokeID = document.getElementById("pokemon-id");
const pokeWeight = document.getElementById("weight");
const pokeHeight = document.getElementById("height");
const pokeTypes = document.getElementById("types");
const pokeHP = document.getElementById("hp");
const pokeAttack = document.getElementById("attack");
const pokeDefense = document.getElementById("defense");
const pokeSpAttack = document.getElementById("special-attack");
const pokeSpDefense = document.getElementById("special-defense");
const pokeSpeed = document.getElementById("speed");
const imageContainer = document.getElementById("image");
const fullList = "https://pokeapi-proxy.freecodecamp.rocks/api/pokemon";

const fetchData = async () => {
  try {
    const res = await fetch(fullList);
    const data = await res.json();
    button.addEventListener("click", () => siftFunction(data))
  } catch (err) {
    console.log(err);
  }
};

fetchData();

const fetchPokeData = async (pokeURL) => {
  try {
    const res = await fetch(pokeURL);
    const data1 = await res.json();
    displayPokemon(data1);
  } catch (err) {
    console.log(err);
  }
};

const displayPokemon = (pokemon) => {
   pokeTypes.innerHTML = "";

   const { name, id, height, weight, sprites, stats, types } = pokemon;
   pokeName.textContent = `${name.toUpperCase()}`;
   pokeID.textContent = `#${id}`;
   pokeWeight.textContent = `Weight: ${weight}`;
   pokeHeight.textContent = `Height: ${height}`;

   const typeName = types.map((item) => {
     const { type } = item;
     const { name } = type;
     return name;
   });
   for (let i = 0; i < typeName.length; i++) {
     pokeTypes.innerHTML += `<span class="${typeName[i]}">  ${typeName[i]}  </span>`;
   };

   const { front_default } = sprites;
   imageContainer.innerHTML = `<img src="${front_default}" alt="${name}" id="sprite"/>`;
   
   const baseStat = stats.map((item) => {
     const { base_stat } = item;
     return base_stat;
   });
   pokeHP.textContent = baseStat[0];
   pokeAttack.textContent = baseStat[1];
   pokeDefense.textContent = baseStat[2];
   pokeSpAttack.textContent = baseStat[3];
   pokeSpDefense.textContent = baseStat[4];
   pokeSpeed.textContent = baseStat[5];
};

const siftFunction = (data) => {
  const userInput = input.value.toLowerCase();
  const { results } = data;
  const name = results.map((item) => {
    const { name } = item;
    return name;
  });
  const id = results.map((item) => {
    const { id } = item;
    return id;
  });

  if (name.includes(userInput) || id.includes(parseInt(userInput))) {
    const pokeURL = `https://pokeapi-proxy.freecodecamp.rocks/api/pokemon/${userInput}`;
    fetchPokeData(pokeURL);
  } else {alert("Pokémon not found")}
};

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36

Challenge Information:

Build a Pokémon Search App Project - Build a Pokémon Search App

hi there,

When I look at the console, I can see an error message that seems to be triggered from the fcc testcase. I’m not sure why exactly, but my guess is that your alert is taking too long to show up and when the test tries to look for the message the first time (test #14), it fails to find it. The testcase waits 2 seconds to give the alert a chance to show but it seems to me that maybe your code is taking longer than that to display it. But that’s a complete and utter guess.

The one thing I noticed that maybe you can look into is that you are relying on searching the full list of pokemon for the name/id before you actually attempt to call the api for the specific pokemon. So you end up calling the api twice. (once to get all the data, then later when the person actually types something). Maybe the time it takes to check if the data set includes the id and name is just a bit too long for this test, but again, that’s just a guess.

In my solution, I only called the API once. If the api gave me a 404 result, then that pokemon didn’t exist, and I could alert. So I’m just mentioning this as an alternative method.

edit: @lasjorg sorry to ping you but maybe you can help out with this one better than I have.

You must have been right, I realize how complicated my process was after reading your reply and once I cut all the extra out, it passed! Thank you!

1 Like

Exactly. Use the API response.


Not that it matters now.

  1. Your parseInt is not behaving as you expect with the random input the test gives it (it is using crypto.randomUUID().substring(0, 6) as the input).

Example input:

console.log(parseInt("5df848")); // 5
  1. Not sure what is going on with the “Red” input, though. It might be that the one-second delay in the test isn’t always enough time because of the two maps and includes in the code, so it might be a race condition. Maybe sometimes, the test tries to read the alert message before it is ready.

on further thought and discussion with someone who helped test this code with a 10s delay in the test, and given they found no change in the test response, now I’m thinking that the real problem may have been that the original code added an eventListener after the first fetch ran. So maybe in those second(s) before it got added, the ‘red’ test was being attempted (and failed due to that).