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

Tell us what’s happening:
I cannot figure out why my code for the Pokémon Search App does not pass tests #15-20, and #22–is it a bug in Free Code Camp, the Pokemon API, or my code? See my code below:

Any help is greatly appreciated!

Your code so far

<!-- file: index.html -->
<!doctype html>
<html>
    <head>
        <title>Pokemon Search App</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="styles.css">
        <link rel="preconnect" href="https://fonts.googleapis.com">
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
        <link href="https://fonts.googleapis.com/css2?family=Pixelify+Sans:wght@400..700&display=swap" rel="stylesheet">
    </head>
    <body>
        <div class="outer-container">
            <h1>Pokemon Search App</h1>
            <input id = "search-input" placeholder = "e.g. pikachu" required/>
            <button id = "search-button">Search</button>
            <div id = "inner-container" class = "inner-container">
            <div id = "error-message"></div>

<!-- POKEMON SNAPSHOT-->
    <div id = "pokemon-snapshot">
        <h2 id = "pokemon-name"></h2>
        <p id = "types"></p>
<div id = "image-container"></div>
        
        <div class = "weight-height">
            <p id = "weight"></p> 
            <p id = "height"></p>
        </div>
        <p id = "pokemon-id"></p>                  
    </div>
<!-- POKEMON STATS-->               
    <div id = "pokemon-stats">
        <h2>stats</h2>
        
        <p id = "hp"></p>
        <p id = "attack"></p>
        <p id = "defense"></p>
        <p id = "special-attack"></p>
        <p id = "special-defense"></p>
        <p id = "speed"></p>
    </div>
            </div>
        </div>
        <script type="module" src="script.js"></script>
    </body>
</html>
/* file: script.js */
let typeData
const searchBtn = document.getElementById("search-button")
const userInput = document.getElementById("search-input")

//POKEMON SNAPSHOT
const pokemonSnapshot = document.getElementById("pokemon-snapshot")
const pokemonName = document.getElementById("pokemon-name")
const pokemonType = document.getElementById("types")
const pokemonImage = document.getElementById("image-container")
const pokemonWeight = document.getElementById("weight")
const pokemonHeight = document.getElementById("height")
const pokemonId = document.getElementById("pokemon-id")

//POKEMON STATS
const pokemonStats = document.getElementById("pokemon-stats")
const pokemonHp = document.getElementById("hp")
const pokemonAttack = document.getElementById("attack")
const pokemonDefense = document.getElementById("defense")
const pokemonSpeed = document.getElementById("speed")
const pokemonSpecialAttack = document.getElementById("special-attack")
const pokemonSpecialDefense = document.getElementById("special-defense")

const errorMessage = document.getElementById("error-message")

 searchBtn.addEventListener("click", getPokemon)
 
 function getPokemon(){
    if (!userInput.value){
        errorMessage.style.display = "flex"
        pokemonSnapshot.innerHTML = ""
        pokemonStats.innerHTML = ""
        errorMessage.innerHTML = `<p>Please enter the name of a pokemon</p>`}
    else {
       
        fetch(`https://pokeapi-proxy.freecodecamp.rocks/api/pokemon/${userInput.value.toLowerCase()}`)
            .then(res => { 
                const contentType = res.headers.get("content-type");
                if (contentType && contentType.indexOf("application/json") !== -1){
                    return res.json().then(data => { 
                        console.log(data)
                        displayStats(data)
} //closes DATA
) //closes IF
}//closes IF 
                else {
                    return res.text().then(text => {
                         errorMessage.style.display = "flex"
                         pokemonSnapshot.innerHTML = ""
                         pokemonStats.innerHTML = ""
                         errorMessage.innerHTML = `
                        <p>Pokémon not found</p>`
alert("Pokémon not found")
                       
} //closes TEXT
)//closes TEXT                     
}//closes ELSE
})
}//closes OuterELSE                                                 
}//closes outermost function                             
 
 function displayStats(data){
    errorMessage.style.display = "none"
      pokemonType.textContent = ""
//POKEMON SNAPSHOT
    pokemonName.textContent =  data.name.toUpperCase()
    pokemonType.innerHTML = `
        <p>${data.types[0].type.name.toUpperCase()}</p>     <p>${data.types[1].type.name.toUpperCase()}</p>`;

    pokemonImage.innerHTML = 
    `<img id = "sprite" src = "${data.sprites.front_default}"/>`
    pokemonWeight.textContent = `Weight: ${data.weight}`
    pokemonHeight.textContent = `Height: ${data.height}`
    pokemonId.textContent = `#${data.id}`

//POKEMON STATS
pokemonHp.textContent = `HP: ${data.stats[0].base_stat}`;
pokemonAttack.textContent = `Attack: ${data.stats[1].base_stat}`
pokemonDefense.textContent = `Defense: ${data.stats[2].base_stat}`;
pokemonSpecialAttack.textContent = `Special Attack: ${data.stats[3].base_stat}`;
pokemonSpecialDefense.textContent = `Special Defense: ${data.stats[4].base_stat}`
pokemonSpeed.textContent = `Speed: ${data.stats[5].base_stat}`;
   
 }
/* file: styles.css */
#sprite{
  height: 50px; 
  width: 50px; 
}

body{
  margin: 10px;
  padding: 0px;
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36 Edg/128.0.0.0

Challenge Information:

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

Hi, please add your code to your post to get help with it.

you have some issues with how you are handling data, this one gets an error that data.types[1] is undefined sometimes (not all pokemons have 2 types, some have only 1)

Hi ilenia! I changed the code so that the element containing the types is now a div with two paragraph elements–one for the first type, and one for the second type if it exists. I made the content in the second paragraph conditional so that it only exists if the pokemon has more than one type, but the app still only retrieves the data for pokemon with two types.

pokemonType.innerHTML = `
    <p>${data.types[0].type.name.toUpperCase()}</p>  
    <p>${data.types[1].type.name? data.types[1].type.name.toUpperCase(): ""}</p>`;

this code doesn’t have any conditional in it.
You need to use an if statement or a ternary to figure out if you should include the 2nd paragraph or not.

this will still give an error if data.types[1] is undefined. do you need to access type and name to check if a second type exist?

I updated my code to the below, and now the search function works. However, I am still not passing tests 15-19, and 22:
//POKEMON SNAPSHOT
pokemonName.textContent = data.name.toUpperCase()
if (data.types.length === 1){
console.log(“only one type!”)
pokemonType.innerHTML = <p>${data.types[0].type.name.toUpperCase()}</p>
}
else {
pokemonType.innerHTML = <p>${data.types[0].type.name.toUpperCase()}</p> <p>${data.types[1].type.name.toUpperCase()}</p>
}

can you post your whole code, properly formatted?

When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

Hey ilenia–see below my JS:

let typeData
const searchBtn = document.getElementById("search-button")
const userInput = document.getElementById("search-input")

//POKEMON SNAPSHOT
const pokemonSnapshot = document.getElementById("pokemon-snapshot")
const pokemonName = document.getElementById("pokemon-name")
const pokemonType = document.getElementById("types")
const pokemonImage = document.getElementById("image-container")
const pokemonWeight = document.getElementById("weight")
const pokemonHeight = document.getElementById("height")
const pokemonId = document.getElementById("pokemon-id")

//POKEMON STATS
const pokemonStats = document.getElementById("pokemon-stats")
const pokemonHp = document.getElementById("hp")
const pokemonAttack = document.getElementById("attack")
const pokemonDefense = document.getElementById("defense")
const pokemonSpeed = document.getElementById("speed")
const pokemonSpecialAttack = document.getElementById("special-attack")
const pokemonSpecialDefense = document.getElementById("special-defense")

const errorMessage = document.getElementById("error-message")

 searchBtn.addEventListener("click", getPokemon)
 
 function getPokemon(){
    if (!userInput.value){
        errorMessage.style.display = "flex"
        pokemonSnapshot.innerHTML = ""
        pokemonStats.innerHTML = ""
        errorMessage.innerHTML = `<p>Please enter the name of a pokemon</p>`}
    else {
       
        fetch(`https://pokeapi-proxy.freecodecamp.rocks/api/pokemon/${userInput.value.toLowerCase()}`)
            .then(res => { 
                const contentType = res.headers.get("content-type");
                if (contentType && contentType.indexOf("application/json") !== -1){
                    return res.json().then(data => { 
                        console.log(data)
                        displayStats(data)
} //closes DATA
) //closes IF
}//closes IF 
                else {
                    return res.text().then(text => {
                         errorMessage.style.display = "flex"
                         pokemonSnapshot.innerHTML = ""
                         pokemonStats.innerHTML = ""
                         errorMessage.innerHTML = `
                        <p>Pokémon not found</p>`
alert("Pokémon not found")
                       
} //closes TEXT
)//closes TEXT                     
}//closes ELSE
})
}//closes OuterELSE                                                 
}//closes outermost function                             
 
 function displayStats(data){
    errorMessage.style.display = "none"
      pokemonType.textContent = ""

//POKEMON SNAPSHOT 
    pokemonName.textContent = data.name.toUpperCase()
    if (data.types.length === 1){
        pokemonType.innerHTML = `
        <p>${data.types[0].type.name.toUpperCase()}</p>`
    }
    else {
        pokemonType.innerHTML = `
        <p>${data.types[0].type.name.toUpperCase()}</p>
         <p>${data.types[1].type.name.toUpperCase()}</p>`
    }
       
    pokemonImage.innerHTML = 
    `<img id = "sprite" src = "${data.sprites.front_default}"/>`
    pokemonWeight.textContent = `Weight: ${data.weight}`
    pokemonHeight.textContent = `Height: ${data.height}`
    pokemonId.textContent = `#${data.id}`

//POKEMON STATS
pokemonHp.textContent = `HP: ${data.stats[0].base_stat}`;
pokemonAttack.textContent = `Attack: ${data.stats[1].base_stat}`
pokemonDefense.textContent = `Defense: ${data.stats[2].base_stat}`;
pokemonSpecialAttack.textContent = `Special Attack: ${data.stats[3].base_stat}`;
pokemonSpecialDefense.textContent = `Special Defense: ${data.stats[4].base_stat}`
pokemonSpeed.textContent = `Speed: ${data.stats[5].base_stat}`;
   
 }

you have an issue tha is illegal nesting, you can’t have a p inside p (#types and its children)

all the errors that appear in the console, TypeError: Cannot read properties of null seems to be because your code takes too much time to execute. I have no idea how to solve