Build an RPG Creature Search App Project - Build an RPG Creature Search App

Tell us what’s happening:

Hep me identify the bug that is failing my code. I have been working on it for some time. I am stuck.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width initial-scale=1.0" />
  <link rel="stylesheet" href="styles.css" />
<title>Build an RPG Creature Search App</title>
</head>

<body>
  <main>
    <div id="main-container">
<h1 class="title">Build an RPG Creature Search App</h1>
  <div id="search-div">
  <label for="search-input"><strong>Search for Crature by Name or ID:</strong></label><br>
  <input type="text" name="creature" id="search-input" required />
<button id="search-button">Search</button> 
  </div>
<div id="creature-info">
<span id="creature-name"></span><span id="creature-id"></span>
<div id="weight"></div>
<div id="height"></div>
</div>
<div id="types"></div>
<div id="base-stats">
  <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>
 <script src="./script.js"></script>
  </main>
  </body>
  </html>
/* file: script.js */
const searchInput = document.getElementById("search-input");
const searchButton = document.getElementById("search-button");
const creatureName = document.getElementById("creature-name");
const creatureID = document.getElementById("creature-id");
const weight = document.getElementById("weight");
const height = document.getElementById("height");
const types = document.getElementById("types");
const hp = document.getElementById("hp");
const attack = document.getElementById("attack");
const defense = document.getElementById("defense");
const specialAttack = document.getElementById("special-attack");
const specialDefense = document.getElementById("special-defense");
const speed = document.getElementById("speed");

const getCreatureData = async () => {
  try {
  const nameOrId = searchInput.value.toLowerCase();

    const res = await fetch(`https://rpg-creature-api.freecodecamp.rocks/api/creature/${nameOrId}`);

    const data = await res.json();
    //console.log(data);
    getCreatureStats(data);
  } catch (err) {
    alert('Creature not found');
    console.log(`Creature not found: ${err}`);
     resetAll;
  }
};

//getCreatureData();

// ...... destructure the creature data ....

const getCreatureStats = data => {
  const {name, id, weight, height, types, stats} = data
  creatureName.textContent = `${name.toUpperCase()}`;
  creatureID.textContent = `#${id}`;
  weight.textContent = `Weight: ${weight}`;
  height.textContent = `Height: ${height}`;
  hp.textContent = stats[0].base_stat;
  attack.textContent = stats[1].base_stat;
  defense.textContent = stats[2].base_stat;
  specialAttack.textContent = stats[3].base_stat;
  specialDefense.textContent = stats[4].base_stat;
  speed.textContent = stats[5].base_stat;

  types.innerHTML = types.map(obj => `<span>${obj.type.name.toUpperCase()}</span>`).join("");
};

const resetAll = () => {
    creatureName.textContent = "";
    creatureID.textContent = "";
    weight.textContent = "";
    height.textContent = "";
    hp.textContent = "";
    attack.textContent = "";
    defense.textContent = "";
    specialAttack.textContent = "";
    specialDefense.textContent = "";
    speed.textContent = "";
    types.innerHTML = "";
}

searchButton.addEventListener ("click", e => {
e.preventDefault();
getCreatureData();
resetAll();
});


/* file: styles.css */

Your browser information:

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

Challenge Information:

Build an RPG Creature Search App Project - Build an RPG Creature Search App

what tests are you failing, what debugging have you tried?

This is the feedback i am getting below:

// running tests 14. When the

#search-input

element contains the value

Red

and the

#search-button

element is clicked, an alert should appear with the text

"Creature not found"

. (Test timed out) 15. When the

#search-input

element contains the value

Pyrolynx

and the

#search-button

element is clicked, the values in the

#creature-name

,

#creature-id

,

#weight

,

#height

,

#hp

,

#attack

,

#defense

,

#special-attack

,

#special-defense

, and

#speed

elements should be

PYROLYNX

,

#1

or

1

,

Weight: 42

or

42

,

Height: 32

or

32

,

65

,

80

,

50

,

90

,

55

, and

100

, respectively. 16. When the

#search-input

element contains the value

Pyrolynx

and the

#search-button

element is clicked, a single element should be added within the

#types

element that contains the text

FIRE

. The

#types

element content should be cleared between searches. (Test timed out) 17. When the

#search-input

element contains the value

2

and the

#search-button

element is clicked, the values in the

#creature-name

,

#creature-id

,

#weight

,

#height

,

#hp

,

#attack

,

#defense

,

#special-attack

,

#special-defense

, and

#speed

elements should be

AQUOROC

,

#2

or

2

,

Weight: 220

or

220

,

Height: 53

or

53

,

85

,

90

,

120

,

60

,

70

, and

40

, respectively. (Test timed out) 18. When the

#search-input

element contains the value

2

and the

#search-button

element is clicked, two elements should be added within the

#types

element that contain text values

WATER

and

ROCK

, respectively. The

#types

element content should be cleared between searches. (Test timed out) 19. When the

#search-input

element contains an invalid creature name and the

#search-button

element is clicked, an alert should appear with the text

"Creature not found"

. (Test timed out) 20. When the

#search-input

element contains a valid creature ID and the

#search-button

element is clicked, the UI should be filled with the correct data. (Test timed out) // tests completed // console output Creature not found: SyntaxError: Unexpected token ‘I’, “Invalid cr”… is not valid JSON Creature not found: TypeError: Cannot create property ‘textContent’ on number ‘42’ [Error: AssertionError: expected [ ‘weight: 42’, ‘42’ ] to include ‘’] Creature not found: TypeError: Cannot create property ‘textContent’ on number ‘42’ [Error: AssertionError: expected to have a length of 1 but got +0] Creature not found: TypeError: Cannot create property ‘textContent’ on number ‘220’ [Error: AssertionError: expected ‘’ to equal ‘aquoroc’] Creature not found: SyntaxError: Unexpected token ‘I’, “Invalid cr”… is not valid JSON

this part is interesting, specifically the start. you can’t res.json() directly, you need first to get the data from that, res.data(), then you can get the json.

when i type the number 16 and click Search button, thisis the feedback i get, plus console.log(data): It means the data has been fetched appropriately, i think because its displaying the creatute plus the ID

Build an RPG Creature Search App

Search for Crature by Name or ID:
Search

BLAZEBORE#16

{ id: 16,
name: ‘Blazebore’,
weight: 250,
height: 54,
special:
{ name: ‘Magma Charge’,
description: ‘Has a 20% chance to set the battlefield on fire, dealing chip damage to non-Fire types.’ },
stats:
[ { base_stat: 90, name: ‘hp’ },
{ base_stat: 120, name: ‘attack’ },
{ base_stat: 80, name: ‘defense’ },
{ base_stat: 75, name: ‘special-attack’ },
{ base_stat: 60, name: ‘special-defense’ },
{ base_stat: 85, name: ‘speed’ } ],
types: [ { name: ‘fire’ }, { name: ‘ground’ } ] }
Creature not found: TypeError: Cannot create property ‘textContent’ on number ‘250’

you should consider this error, it’s stopping the execution of the code

note, you can’t have multiple variables with the same name

I am still stack at step 15, 16, 17, 18 and 20. And sometimes step 14 doesnt pass because it’s timed out. The URL for the API endpoint we are using appears to be incorrect but when I use [https://pokeapi-proxy.freecodecamp.rocks/api/pokemon/](https://pokeapi-proxy.freecodecamp.rocks/api/pokemon/) URL, the APP seems to be working .

# Build an RPG Creature Search App

**Search for Crature by Name or ID:**
Search

RATTATA#19

Weight: 35

Height: 3

NORMAL

HP: 30

Attack: 56

Defense: 35

Special Attack: 25

Special Defense: 35

Speed: 72
const searchInput = document.getElementById("search-input");
const searchButton = document.getElementById("search-button");
const creatureName = document.getElementById("creature-name");
const creatureID = document.getElementById("creature-id");
const weight = document.getElementById("weight");
const height = document.getElementById("height");
const typesDiv = document.getElementById("types"); 
const hp = document.getElementById("hp");
const attack = document.getElementById("attack");
const defense = document.getElementById("defense");
const specialAttack = document.getElementById("special-attack");
const specialDefense = document.getElementById("special-defense");
const speed = document.getElementById("speed");

const getCreatureData = async () => {
  try {
    const nameOrId = searchInput.value.toLowerCase();

    if (!nameOrId) {
      alert("Please enter a creature name or ID!");
      resetAll();
      return;
    }

    const res = await fetch(`https://rpg-creature-api.freecodecamp.rocks/api/creature/${nameOrId}`);

    if (!res.ok) {
      throw new Error('Creature not found');
    }

    const data = await res.json();
    console.log(data);
    getCreatureStats(data);
  } catch (err) {
    console.error(`Error fetching creature data: ${err.message}`);
    alert(err.message);
    resetAll();
  }
};

const getCreatureStats = data => {
  const {
    name,
    id,
    weight: creatureWeight,
    height: creatureHeight,
    types,
    stats
  } = data;

  creatureName.textContent = `${name.toUpperCase()}`;
  creatureID.textContent = `#${id}`;
  weight.textContent = `Weight: ${creatureWeight}`; 
  height.textContent = `Height: ${creatureHeight}`; 

  hp.textContent = `HP: ${stats[0].base_stat}`;
  attack.textContent = `Attack: ${stats[1].base_stat}`;
  defense.textContent = `Defense: ${stats[2].base_stat}`;
  specialAttack.textContent = `Special Attack: ${stats[3].base_stat}`;
  specialDefense.textContent = `Special Defense: ${stats[4].base_stat}`;
  speed.textContent = `Speed: ${stats[5].base_stat}`;

  typesDiv.innerHTML = types.map(obj => `<span>${obj.type.name.toUpperCase()}</span>`).join("");
};

const resetAll = () => {
  creatureName.textContent = "";
  creatureID.textContent = "";
  weight.textContent = "";
  height.textContent = "";
  hp.textContent = "";
  attack.textContent = "";
  defense.textContent = "";
  specialAttack.textContent = "";
  specialDefense.textContent = "";
  speed.textContent = "";
  typesDiv.innerHTML = ""; 
};

searchButton.addEventListener("click", e => {
  e.preventDefault();
  getCreatureData();
});

ERROR MESSAGES:
// running tests
15. When the #search-input element contains the value Pyrolynx and the #search-button element is clicked, the values in the #creature-name, #creature-id, #weight, #height, #hp, #attack, #defense, #special-attack, #special-defense, and #speed elements should be PYROLYNX, #1 or 1, Weight: 42 or 42, Height: 32 or 32, 65, 80, 50, 90, 55, and 100, respectively.
16. When the #search-input element contains the value Pyrolynx and the #search-button element is clicked, a single element should be added within the #types element that contains the text FIRE. The #types element content should be cleared between searches.
17. When the #search-input element contains the value 2 and the #search-button element is clicked, the values in the #creature-name, #creature-id, #weight, #height, #hp, #attack, #defense, #special-attack, #special-defense, and #speed elements should be AQUOROC, #2 or 2, Weight: 220 or 220, Height: 53 or 53, 85, 90, 120, 60, 70, and 40, respectively.
18. When the #search-input element contains the value 2 and the #search-button element is clicked, two elements should be added within the #types element that contain text values WATER and ROCK, respectively. The #types element content should be cleared between searches.
20. When the #search-input element contains a valid creature ID and the #search-button element is clicked, the UI should be filled with the correct data.

// tests completed
// console output
Error fetching creature data: Creature not found
{ id: 1,
  name: 'Pyrolynx',
  weight: 42,
  height: 32,
  special: 
   { name: 'Blazing Reflex',
     description: 'Increases speed when hit by a Fire-type move.' },
  stats: 
   [ { base_stat: 65, name: 'hp' },
     { base_stat: 80, name: 'attack' },
     { base_stat: 50, name: 'defense' },
     { base_stat: 90, name: 'special-attack' },
     { base_stat: 55, name: 'special-defense' },
     { base_stat: 100, name: 'speed' } ],
  types: [ { name: 'fire' } ] }
Error fetching creature data: Cannot read properties of undefined (reading 'name')
[Error: AssertionError: expected '' to equal 'pyrolynx']
{ id: 1,
  name: 'Pyrolynx',
  weight: 42,
  height: 32,
  special: 
   { name: 'Blazing Reflex',
     description: 'Increases speed when hit by a Fire-type move.' },
  stats: 
   [ { base_stat: 65, name: 'hp' },
     { base_stat: 80, name: 'attack' },
     { base_stat: 50, name: 'defense' },
     { base_stat: 90, name: 'special-attack' },
     { base_stat: 55, name: 'special-defense' },
     { base_stat: 100, name: 'speed' } ],
  types: [ { name: 'fire' } ] }
Error fetching creature data: Cannot read properties of undefined (reading 'name')
[Error: AssertionError: expected  to have a length of 1 but got +0]
{ id: 2,
  name: 'Aquoroc',
  weight: 220,
  height: 53,
  special: 
   { name: 'Tidal Barrier',
     description: 'Reduces damage from Fire and Ice attacks by 50%.' },
  stats: 
   [ { base_stat: 85, name: 'hp' },
     { base_stat: 90, name: 'attack' },
     { base_stat: 120, name: 'defense' },
     { base_stat: 60, name: 'special-attack' },
     { base_stat: 70, name: 'special-defense' },
     { base_stat: 40, name: 'speed' } ],
  types: [ { name: 'water' }, { name: 'rock' } ] }
Error fetching creature data: Cannot read properties of undefined (reading 'name')
[Error: AssertionError: expected '' to equal 'aquoroc']
{ id: 2,
  name: 'Aquoroc',
  weight: 220,
  height: 53,
  special: 
   { name: 'Tidal Barrier',
     description: 'Reduces damage from Fire and Ice attacks by 50%.' },
  stats: 
   [ { base_stat: 85, name: 'hp' },
     { base_stat: 90, name: 'attack' },
     { base_stat: 120, name: 'defense' },
     { base_stat: 60, name: 'special-attack' },
     { base_stat: 70, name: 'special-defense' },
     { base_stat: 40, name: 'speed' } ],
  types: [ { name: 'water' }, { name: 'rock' } ] }
Error fetching creature data: Cannot read properties of undefined (reading 'name')
[Error: AssertionError: expected  to have a length of 2 but got +0]
Error fetching creature data: Creature not found
{ id: 19,
  name: 'Titanule',
  weight: 490,
  height: 77,
  special: 
   { name: 'Iron Tide',
     description: 'Raises Defense in rainy weather.' },
  stats: 
   [ { base_stat: 130, name: 'hp' },
     { base_stat: 95, name: 'attack' },
     { base_stat: 140, name: 'defense' },
     { base_stat: 60, name: 'special-attack' },
     { base_stat: 90, name: 'special-defense' },
     { base_stat: 30, name: 'speed' } ],
  types: [ { name: 'steel' }, { name: 'water' } ] }
Error fetching creature data: Cannot read properties of undefined (reading 'name')
[Error: AssertionError: expected  to have a length of 2 but got +0]

Well, if I try to write Pyrolynx in the search box and press the button, I see this:

Didn’t you try your app?

Yes, I did. The property “name” should be part of the Creatures data in API. I don’t what I am doing wrong. I am stuck. though I am still working on the code to see what I am missing. Kindly guide me!

It isn’t the name property that is undefined, it is the “thing” you are trying to access the property on that is undefined.

Hint, check the “thing” left of the dot for the name property.

typesDiv.innerHTML = types.map(obj => `<span>${obj.type.name.toUpperCase()}</span>`).join("");

I am stuck again on no. 15 and 17.
here is the output whwn I run my code:

output Error fetching creature data: Creature not found [Error: AssertionError: expected ‘HP: 65’ to equal ‘65’] [Error: AssertionError: expected ‘HP: 85’ to equal ‘85’] Error fetching creature data: Creature not found

const searchInput = document.getElementById("search-input");
const searchButton = document.getElementById("search-button");
const creatureName = document.getElementById("creature-name");
const creatureID = document.getElementById("creature-id");
const weight = document.getElementById("weight");
const height = document.getElementById("height");
const typesDiv = document.getElementById("types"); 
const hp = document.getElementById("hp");
const attack = document.getElementById("attack");
const defense = document.getElementById("defense");
const specialAttack = document.getElementById("special-attack");
const specialDefense = document.getElementById("special-defense");
const speed = document.getElementById("speed");

const getCreatureData = async () => {
  try {
    const nameOrId = searchInput.value.toLowerCase();

    if (!nameOrId) {
      alert("Please enter a creature name or ID!");
      resetAll();
      return;
    }

    const res = await fetch(`https://rpg-creature-api.freecodecamp.rocks/api/creature/${nameOrId}`);

    if (!res.ok) {
      throw new Error('Creature not found');
    }

    const data = await res.json();
    //console.log(data);
    getCreatureStats(data);
  } catch (err) {
    console.error(`Error fetching creature data: ${err.message}`);
    alert(err.message);
    resetAll();
  }
};

const getCreatureStats = data => {
  const {
    name,
    id,
    weight: creatureWeight,
    height: creatureHeight,
    types,
    stats
  } = data;

  creatureName.textContent = `${name.toUpperCase()}`;
  creatureID.textContent = `#${id}`;
  weight.textContent = `Weight: ${creatureWeight}`; 
  height.textContent = `Height: ${creatureHeight}`; 

  hp.textContent = `HP: ${stats[0].base_stat}`;
  attack.textContent = `Attack: ${stats[1].base_stat}`;
  defense.textContent = `Defense: ${stats[2].base_stat}`;
  specialAttack.textContent = `Special Attack: ${stats[3].base_stat}`;
  specialDefense.textContent = `Special Defense: ${stats[4].base_stat}`;
  speed.textContent = `Speed: ${stats[5].base_stat}`;

  typesDiv.innerHTML = types.map(obj => `<span class="type ${obj.name}">${obj.name.toUpperCase()}</span>`).join("");
};

const resetAll = () => {
  creatureName.textContent = "";
  creatureID.textContent = "";
  weight.textContent = "";
  height.textContent = "";
  hp.textContent = "";
  attack.textContent = "";
  defense.textContent = "";
  specialAttack.textContent = "";
  specialDefense.textContent = "";
  speed.textContent = "";
  typesDiv.innerHTML = ""; 
};

searchButton.addEventListener("click", e => {
  e.preventDefault();
  getCreatureData();
});

you are getting this, can you investigate what it is telling you?

1 Like

I have managed to debug the error and my project has passed! thank you for the guidance.

bro can you share the corrected code as i have been stuck on same problem for a long time ?

this is a certification project, you can ask for help (you should create your own topic for that), but it is against the Academic Honesty Policy to use other people’s code