Build a Pokémon Search App Project

Hello! I’m struggling to identify where the problems lies and can’t pass the 2 conditions below :

  1. When the #search-input element contains the value Pikachu and the #search-button element is clicked, the values in the #pokemon-name , #pokemon-id , #weight , #height , #hp , #attack , #defense , #special-attack , #special-defense , and #speed elements should be PIKACHU , #25 or 25 , Weight: 60 or 60 , Height: 4 or 4 , 35 , 55 , 40 , 50 , 50 , and 90 , respectively.

  2. When the #search-input element contains the value 94 and the #search-button element is clicked, the values in the #pokemon-name , #pokemon-id , #weight , #height , #hp , #attack , #defense , #special-attack , #special-defense , and #speed elements should be GENGAR , #94 or 94 , Weight: 405 or 405 , Height: 15 or 15 , 60 , 65 , 60 , 130 , 75 , and 110 , respectively.

HTML -

<h1>Pokémon Search App</h1>
<div class="app">
<div class="header-container">
<p class="title" id="title">Search for Pokémon Name or ID:</p>
<input class="search-input" id="search-input" required>
<button class="search-button" id="search-button">Search</button>
</div>
<div class="pokemon-info-container">
  <p class="pokemon-name" id="pokemon-name"></p>
  <p class="pokemon-id" id="pokemon-id"></p>
  <p class="weight" id="weight"></p>
  <p class="height" id="height"></p>
  <div class="types" id="types">
  </div>
  <div class="pokemon-sprite" id="pokemon-sprite">
  </div>
  </div>
  <div class="stats-grid">
  <div class="classification" id="types">Base
  </div>
  <div class="stats-number">Stats</div>
  <div class="classification" id="hp">HP:</div>
  <div class="stats-number-hp" id="stats-number-hp"></div>
  <div class="classification" id="attack">Attack:
  </div>
  <div class="stats-number-attack" id="stats-number-attack"></div>
  <div class="classification" id="defense">Defense:</div>
  <div class="stats-number-defense" id="stats-number-defense"></div>
  <div class="classification" id="special-attack">Sp. Attack:</div>
  <div class="stats-number-special-attack" id="stats-number-special-attack"></div>
  <div class="classification" id="special-defense">Sp. Defense:</div>
  <div class="stats-number-special-defense" id="stats-number-special-defense"></div>
  <div class="classification" id="speed">Speed:</div>
  <div class="stats-number-speed" id="stats-number-speed"></div>
</div>
</div>

CSS -

body {
margin: 0;
padding: 0;
background-color: #263238;
font-family: sans-serif;
color: black;
}

  • {
    box-sizing: border-box;
    }

h1 {
text-align: center;
}

.app {
background-color: orange;
width: 50%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 0 auto;
min-width: 300px;
border-radius: 20px;
}

.header-container {
text-align: center;
}

.search-input {
font-size: 18px;
padding: 8px;
border-radius: 4px;
border: none;
width: auto;
}

.search-button {
padding: 10px;
border-radius: 10px;
border: none;
margin-top: 10px;
}

.pokemon-info-container {
background-color: #ECEFF1;
width: 90%;
height: 300px;
margin-top: 20px;
padding-left: 20px;
position: relative;
}

.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 5px;
text-align: center;
font-size: 18px;
margin-top: 30px;
}

.classification {
background-color: purple;
padding: 10px 0;
width: 200px;
}

.stats-number,
.stats-number-hp,
.stats-number-attack,
.stats-number-defense,
.stats-number-special-attack,
.stats-number-special-defense,
.stats-number-speed{
background-color: purple;
padding: 10px 0;
}

.pokemon-name,
.pokemon-id {
display: inline-block;
margin-right: 10px;
}

.weight,
.height {
font-size: 12px;
}

.types {
position: absolute;
bottom: 0;
background-color: orange;
padding: 10px;
border: none;
border-radius: 6px;
font-size: 13px;
}

.pokemon-sprite {
display: flex;
justify-content: center;
align-items: center;
}

Javascript -

  const searchInput = document.getElementById("search-input");
  const searchBtn = document.getElementById("search-button");
  const pokemonName = document.getElementById("pokemon-name");
  const pokemonId = document.getElementById("pokemon-id");
  const pokemonWeight = document.getElementById("weight");
  const pokemonHeight = document.getElementById("height");
  const typesDisplay = document.getElementById("types");
  const pokemonSprite = document.getElementById("pokemon-sprite");

  const hpDisplay = document.getElementById("stats-number-hp");
  const attackDisplay = document.getElementById("stats-number-attack");
  const defenseDisplay = document.getElementById("stats-number-defense");
  const specialAttackDisplay = document.getElementById("stats-number-special-attack");
  const specialDefenseDisplay = document.getElementById("stats-number-special-defense");
  const speedDisplay = document.getElementById("stats-number-speed");
  
  const apiFetch = async () => {
    try {
      const res = await fetch(`https://pokeapi-proxy.freecodecamp.rocks/api/pokemon/${searchInput.value.toLowerCase()}`);
      if (!res.ok) {
        throw new Error("oops error")
      }
      const data = await res.json();
      displayPokemon(data);
    } catch (err) {
      console.log("ERROR", err);
      alert("Pokémon not found");
    }
  }

  const displayPokemon = (data) => {
    pokemonName.textContent = data.name.toUpperCase();
    pokemonId.textContent = `#${data.id}`;
    pokemonWeight.textContent = `Weight: ${data.weight}`;
    pokemonHeight.textContent = `Height: ${data.height}`;

    data.types.forEach((data) => {
      const button = document.createElement("button");
      button.textContent = data.type.name.toUpperCase();
      typesDisplay.append(button)
      });
      
    hpDisplay.textContent = data.stats.find(stat => stat.stat.name === "hp").base_stat;
    attackDisplay.textContent = data.stats.find(stat => stat.stat.name === "attack").base_stat;
    defenseDisplay.textContent = data.stats.find(stat => stat.stat.name === "defense").base_stat;
    specialAttackDisplay.textContent = data.stats.find(stat => stat.stat.name === "special-attack").base_stat;
    specialDefenseDisplay.textContent = data.stats.find(stat => stat.stat.name === "special-defense").base_stat;
    speedDisplay.textContent = data.stats.find(stat => stat.stat.name === "speed").base_stat;

    pokemonSprite.innerHTML += `<img id="sprite" src="${data.sprites.front_default}" alt="${data.name}sprite">`
    }

    const resetDisplay = () => {
      typesDisplay.innerText = "";
      pokemonSprite.innerText = "";
    }

  searchBtn.addEventListener("click", () => {
    apiFetch();
    resetDisplay();
  });
  
  searchInput.addEventListener("keydown", (e) => {
    if (e.key === "Enter") {
      apiFetch();
      resetDisplay();
    }
  })

I do apologise if the format is incorrect, this is my first time making a forum post here.

Welcome to the forum @senzhao123

Try placing the stat name and stat data on the same line, separated by a single space.

Happy coding

1 Like

YES!!! that worked!!! My first thought from the hint was it was directing me to the data.stats portion but after some more thinking i realised this hint could be about the HTML and changing some of my DOM’s.

Very appreciative of the nudge to the the right direction and thank you for your guidance .

1 Like