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

Tell us what’s happening:

Hello ! I can’t figure out why my code isn’t passing the following test :

“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.”

And the similar ones, even if when I run manually the code, it works

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">
    <link href="styles.css" rel="stylesheet">
     <title> PokéAPI Proxy</title>
</head>
    
    <body>
      <header>
        <h1> Pokédex </h1>
        </header>
      <main>
         
          <div id="search">
          <form onsubmit="return false"> 
            <input type="text" id="search-input" placeholder="Pokemon" required>
            <button type="submit" id="search-button">Attrapez-les tous ! </button>
            </form>
            </div>
          <div id="card">
            <div id="main-info">
            <div id="pokemon-name"></div>
            <div id="pokemon-id"></div>
            </div>
            <div id="pokemon_avatar"></div>
            <div id="pokemon-detail">
              <div id="weight"></div>
              <div id="height"></div>
              <div id="types"></div>
              <div id="hp"></div>
              <div id="attack"></div>
              <div id="defense"></div>
              <div id="special-attack"></div>
              <div id="special-defense"></div>
              <div id="speed"></div>
            </div>
            <div id="pokemon-stats">
              </div>
          </div>
        </main>
        <footer>
          made by I.A
          </footer>
      <script src="script.js"></script>
      </body>
      </html>

const searchButton = document.getElementById("search-button");
 async function seek(recherche){
  const url = `https://pokeapi-proxy.freecodecamp.rocks/api/pokemon/${recherche}`
try {
const r = await fetch(url)
  if(!r.ok){
      throw new Error("Cannot connect to the pokemon library")
  }
  return r.json()
} catch(error){
  alert("Pokemon not found")
    throw new Error("Pokémon not found");
}
};

async function search(){
const searchInput= document.getElementById("search-input").value
const numSearch = parseFloat(searchInput);
let recherche; 
if(isNaN(numSearch)){
   recherche = searchInput.charAt(0).toLowerCase() + searchInput.substring(1)
  
} else{
  recherche = numSearch;
}

const data = await seek(recherche);
const inPage=(data)=>{
function renderData(data){
const divCard=document.getElementById("card");
divCard.classList.add("card-active");
const { base_experience, height, id, name, order, sprites, stats, types, weight } = data;
const {back_default, front_default}= sprites;
const [{ base_stat: stat1 }, { base_stat: stat2 }, { base_stat: stat3 }, { base_stat: stat4 }, { base_stat: stat5 }, { base_stat: stat6 }] = stats;
const pokemonId= document.getElementById("pokemon-id");
pokemonId.innerHTML=` #${id}`;
const pokemonName = document.getElementById("pokemon-name");
pokemonName.innerHTML= `${name.toUpperCase()}`;
const pokemonHeight = document.getElementById("height");
pokemonHeight.innerHTML=` Height: ${height}`;
const pokemonWeight = document.getElementById("weight");
pokemonWeight.innerHTML=`Weight: ${weight}`;
const pokemonSpritesFront = document.getElementById("pokemon_avatar");
pokemonSpritesFront.innerHTML=`<img id="sprite" src="${front_default}" alt ="${name} avatar">`;
const typeNames = types.map(type => type.type.name);
const pokemonType = document.getElementById("types");
 pokemonType.innerHTML = ""; 
typeNames.forEach((typeName) => {
    pokemonType.innerHTML += `${typeName.toUpperCase()}<br>`;
});
const baseStats = ["HP:","Attack:","Defense:","Special-Attack:","Special-Defense:","Speed:"];
const statsArray = stats.map(stat => stat.base_stat);
const pokemonStats = document.getElementById("pokemon-stats");
let statsHTML="<table><tr><td> Base </td><td> Stats </td></tr>";
statsArray.forEach((stat, index)=>{
  const base = baseStats[index];
  statsHTML += `<tr><td id="${base.toLowerCase().slice(0,-1)}">${base}</td><td>${stat}</td></tr>`
  console.log(base.toLowerCase().slice(0,-1))
});
statsHTML += "</table>";
pokemonStats.innerHTML= statsHTML;
}
renderData(data)
}
inPage(data)
}
searchButton.addEventListener('click', search);

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) 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

You may be running into server errors, open the inspector and the console is saying FCC pokemon and the others that are no passing. A lot of 404`s there which is server issues.

Is it my fault ? Did I write something badly ? Is that because of the way i’m dealing with errors ?

Thank you for your reply, btw !

consider that throwing an error means things stop working

Hello,
I have run and tested your codes, the test want to see value of ‘hp’, ‘attack’ or ‘defense’ inside of the related id’s element. But in your table, ids point at the name (base variable) of the value, not directly to value. The id should be placed on the element corresponding to the stat variable.

Edit: The error is not confined to this, sorry. I’m currently investigating… :flushed:

Edit2:
First of all, here’s the issue:

You’ve placed the expected stat IDs into div elements and created them in the HTML file, but later, when you map through the stats and place them, you’re creating new table columns with the same IDs.

To fix this, you can either hard code the table into the HTML and then change it with getElementById according to the IDs, or you can dynamically create the table, but you shouldn’t use the same IDs in the HTML section (although when I tried this method, the test wanted to see these HTML elements with the same ID first in the first stages without any search, so you’ll need to add these elements dynamically without any search).

Suggestions and potential error blockers:

  • Additionally, moving all the getElementById calls outside of the async function and assigning them to a global variable at the beginning would be the healthiest approach.
  • Instead of directly running an async function in the button click event listener, defining a separate buttonHandler function and first checking if the input is valid before passing this input to the async search function would be more appropriate.
  • Fetching the data in the async function and then manipulating the DOM with a non-async function, filling variables like stat and name, would be more reliable. You can use this by calling the function after the data has been fetched correctly.
  • You’ve defined too many nested functions, you can define the functions in a separate place, and you can perform the operations in the renderData function without the need for a separate function named inPage.
  • Finally, if you clean up operations like types, it might be healthier to do this every time a button is clicked in the buttonHandler.

Edit3:
Test want to see to types with single inner element,

So you can create a new element for each type like as span or p element. Also you can make each type different color or style with this approach.

I hope this will help you. Happy coding :slightly_smiling_face:.

1 Like

That’s the direction I was heading in, thanks for reassuring me. I’ve finally reviewed the way I handled errors in my try catches, but I had no idea that I could manage this in a dedicated section. Thanks again for all your tips!

And if finally that error isn’t only my fault, at least it made me think about a better way to manage my code !

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.