Build a Pokémon Search App - tests fail

Hello everyone, I see the result, described in the tests, but I get the errors:

15. 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.
16. When the #search-input element contains the value Pikachu and the #search-button element is clicked, you should add an img element with the id of "sprite" and the src set to the Pokémon's front_default sprite to the page.
17. When the #search-input element contains the value Pikachu and the #search-button element is clicked, the #types element should contain a single inner element with the value ELECTRIC. Make sure the #types element content is cleared between searches.
20. When the #search-input element contains the value 94 and the #search-button element is clicked, the #types element should contain two inner elements with the text values GHOST and POISON, respectively. Make sure the #types element content is cleared between searches.
22. When the #search-input element contains a valid Pokemon id and the #search-button element is clicked, the UI should be filled with the correct data.
// tests completed
// console output
[Error: AssertionError: expected '' to equal 'pikachu']
[Error: TypeError: sprite is null]
[Error: AssertionError: expected  to have a length of 1 but got +0]
[Error: AssertionError: expected  to have a length of 2 but got +0]
[Error: AssertionError: expected  to have a length of 2 but got +0]

HTML:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta name="description" content="Webpage description goes here" />
  <meta charset="utf-8">
  <title>Change_me</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="author" content="KO">
<link
  rel="stylesheet"
  href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
>
    <link rel="stylesheet" href="./style.css">
  
</head>

<body><main class="container">
  <input required type="text" id="search-input">
<button id="search-button">Search</button>
<div id="pokemon-name"></div>
<div id="pokemon-id"></div>
<div id="pokemon-img"></div>
<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>
<script src="./script.js"></script></main>
</body>
</html>

script.js:

const searchInput = document.getElementById("search-input");
const searchButton = document.getElementById("search-button");
const search  = async () => {
  const baseUrl = 'https://pokeapi-proxy.freecodecamp.rocks/api/pokemon';

async function resetStat() {
      document.getElementById("pokemon-name").textContent = '';
      document.getElementById("pokemon-id").textContent = '';
      document.getElementById("pokemon-img").innerHTML = '';
      document.getElementById("weight").textContent = '';
      document.getElementById("height").textContent = '';
      const typeNames = '';
      document.getElementById("types").textContent = typeNames;
      const statArr = ['hp', 'attack', 'defense', 'special-attack', 'special-defense', 'speed'];
      statArr.forEach ((stat) => {
        document.getElementById(stat).textContent = '';
      });
  }

  function findPokemonByName(pokemonName) {
    try {
      const pokemonUrl = fetch(baseUrl)
      .then((res) => res.json())
      .then((data) => {
        const foundPokemon = data.results.find(pokemon => pokemon.name.toLowerCase() === pokemonName || pokemon.id === Number(pokemonName));
        return foundPokemon ? foundPokemon.url : "Not found";
        })
      return pokemonUrl;
    } catch(err) {
      resetStat();
      alert("Pokémon not found");
    }
  }
  
  function getPokemonStat(data, statName) {
    const statPart = data.stats.find(stat => stat.stat.name === statName);
    const statValue = statPart ? statPart.base_stat : null;
    return statValue;
  }

  async function getPokemonData(pokemonUrl) {
    const pokemonData = fetch(pokemonUrl)
    .then((res) => res.json())
    .then((data) => {
      document.getElementById("pokemon-name").textContent = data.name.toUpperCase();
      document.getElementById("pokemon-id").textContent = data.id;
      document.getElementById("pokemon-img").innerHTML = `<img src="${data.sprites.front_default}" id="sprite">`;
      document.getElementById("weight").textContent = 'Weight: ' + data.weight;
      document.getElementById("height").textContent = 'Height: ' + data.height;
      const typeNames = data.types.map(typeObj => typeObj.type.name.toUpperCase()).join(' ');
      document.getElementById("types").textContent = typeNames;
      const statArr = ['hp', 'attack', 'defense', 'special-attack', 'special-defense', 'speed'];
      statArr.forEach ((stat) => {
        document.getElementById(stat).textContent = getPokemonStat(data, stat);
      });
    });
  }

   async function getPokemonData(pokemonUrl) {
    const pokemonData = fetch(pokemonUrl)
    .then((res) => res.json())
    .then((data) => {
      console.log(data);
      document.getElementById("pokemon-name").textContent = data.name.toUpperCase();
      document.getElementById("pokemon-id").textContent = data.id;
      document.getElementById("pokemon-img").innerHTML = `<img src="${data.sprites.front_default}" id="sprite-container">`;
      document.getElementById("weight").textContent = 'Weight: ' + data.weight;
      document.getElementById("height").textContent = 'Height: ' + data.height;
      const typeNames = data.types.map(typeObj => typeObj.type.name.toUpperCase()).join(' ');
      document.getElementById("types").textContent = typeNames;
      const statArr = ['hp', 'attack', 'defense', 'special-attack', 'special-defense', 'speed'];
      statArr.forEach ((stat) => {
        document.getElementById(stat).textContent = getPokemonStat(data, stat);
      });
    });
  }



  const searchValue = searchInput.value;
  
  if (searchValue.includes('Red')) {
    resetStat();
    alert("Pokémon not found");
  } else {
    const pokemonUrl = await findPokemonByName(searchValue);
    if (pokemonUrl !== 'Not found') {
      const pokemonResult = await getPokemonData(pokemonUrl);
    } else {
      resetStat();
      alert("Pokémon not found");
    }
  } 
}

searchButton.addEventListener('click', search);

O caminho está certo?

put this after main, not inside it

  • Do not nest functions unnecessarily. There is no reason to nest all the functions inside the click handler.

  • You have declared getPokemonData twice.

  • You are lower casing the wrong value in the find method, the API gives you lower case names.

  • Your image element does not have the correct required id.

  • For the height and weight, you are added text to the element that should only contain the date from the API. If you want to “label” the values, the labels can not be inside the same element as the expected data.

  • Your types element should contain an inner element for each of type data return by the API.

  • Make sure you clear the DOM between searches.

  • Do not hardcode for the search "Red", use the API return to figure out if something can be found or not.

Thank you so much!
You should definitely provide a link so I could buy you a coffee. :slight_smile:

For those who are interested, the corrected version for script.js:

const searchInput = document.getElementById("search-input");
const searchButton = document.getElementById("search-button");
const specs = document.getElementById('pokemon-specs');


async function resetStat() {
       document.getElementById("pokemon-name").textContent = '';
      document.getElementById("pokemon-id").textContent = '';
      const sprite = document.getElementById("sprite");
      if (sprite) sprite.remove();
      document.getElementById("weight").textContent = '';
      document.getElementById("height").textContent = '';
      document.getElementById("types").innerHTML = '';
      const statArr = ['hp', 'attack', 'defense', 'special-attack', 'special-defense', 'speed'];
      statArr.forEach ((stat) => {
        document.getElementById(stat).textContent = '';
      });
  }

  async function findPokemonByName(pokemonName, baseUrl) {
    try {
      const response = await fetch(baseUrl);
      const data = await response.json();
      const foundPokemon = data.results.find(pokemon => pokemon.name === pokemonName || pokemon.id === Number(pokemonName));
      return foundPokemon ? foundPokemon.url : "Not found";
    } catch(err) {
      return("Not found");
    }
  }
  
  function getPokemonStat(data, statName) {
    const statPart = data.stats.find(stat => stat.stat.name === statName);
    const statValue = statPart ? statPart.base_stat : null;
    return statValue;
  }

  async function getPokemonData(pokemonUrl) {
    const pokemonData = await fetch(pokemonUrl)
    .then((res) => res.json())
    .then((data) => {
      document.getElementById("pokemon-name").textContent = data.name.toUpperCase();
      document.getElementById("pokemon-id").textContent = data.id;
      document.getElementById("pokemon-img").innerHTML = `<img id="sprite" src="${data.sprites.front_default}" alt="${data.name} front default sprite">`;
      document.getElementById("weight").textContent = data.weight;
      document.getElementById("height").textContent = data.height;
      const typeNames = data.types.map(typeObj => `<span>${typeObj.type.name.toUpperCase()}</span>`).join(' ');
      document.getElementById("types").innerHTML = typeNames;
      const statArr = ['hp', 'attack', 'defense', 'special-attack', 'special-defense', 'speed'];
      statArr.forEach ((stat) => {
        document.getElementById(stat).textContent = getPokemonStat(data, stat);
      });
    });
    return;
  }

const search  = async () => {
  const baseUrl = 'https://pokeapi-proxy.freecodecamp.rocks/api/pokemon';
  const searchValue = searchInput.value;
  if (!searchValue) {
    resetStat();
    return;
  }
  const pokemonUrl = await findPokemonByName(searchValue.toLowerCase(), baseUrl);
   if (pokemonUrl !== 'Not found') {
        await getPokemonData(pokemonUrl);
    } else {
        resetStat();
        alert("Pokémon not found");
    }
}

searchButton.addEventListener('click', search);

Hi there @ikostas . It’s great that you passed the challenge. But posting full working solution code isn’t allowed here on the forum.

I think it is fine when asking for help to post the updated code. Otherwise, we can’t really check it. But it should be blurred to avoid spoilers.

We have blurred this solution (with [spoiler][/spoiler] tags) so that users who have not completed this challenge can read the discussion in this thread without giving away the solution.