I need help adding dynamic styles to my pokemon app

Hello! I am looking for help in changing the background color of the pokemon type element which is typesEl. For instance, if the pokemon has a type of electric, the background color should return yellow, if it is a water type, it should have a background color of lightblue for this element. I commented the area at issue. Any help would be much appreciated!
Pokemon Search App (scrimba.com)

Ok, I see the issue here. Try console.log(typesEl) and you will get null. Why? Think about the order of your code - elements can’t be accessed before they have been created!

Hope that pushes you in the right direction…but if not, come back and ask for more!

Tom–thank you so much for helping me! I got it working :smiley: One more little thing I am trying to figure out–I want to throw an error message if the user enters in a name that isn’t a pokemon i.e. the API doesn’t find a pokemon with that name. I created a comment in the area I would like to add it to–right now I have: if (userInput.value === “”){
console.log(“this is a place holder and an error message will show on the screen at a later time!”)
} Any hints would be greatly appreciated!

Pokemon Search App (scrimba.com)

This is actually quite a tricky one!

So this API does one of two things, essentially.

  1. You ask for a pokemon that exists - it gives you JSON.
  2. You ask for a pokemon that doesn’t exist - it gives you TEXT.

At the moment, you are calling .json() on the res, which is fine when you input a real pokemon, but fails when you input anything else. What happens is you get a text response but you try to parse it as JSON and that fails. If you do res.text() instead, and then input “abc”, you will see it in action.

Added to this, you are also checking if the user has inputted anything at all. This should not be done here. Do that before making the API request.

So it needs to go something like this:

  1. Event listener fires
  2. Check if user has inputted text. If not, prompt them but don’t make api fetch request.
  3. If they have, make API fetch request
  4. Take response from API and figure out if it is JSON or TEXT.
  5. If it’s JSON, the code you have can run. If it’s TEXT, you need to do something else (tell the user what they entered, which is basically what the TEXT the api gives you says.)

Have a think about that and get back to me if you are still stuck!

Got it working–thanks Tom! Now there is just one last feature I am stuck with–when I go from typing in an invalid Pokemon name to typing in a valid one, or I leave the input blank and press the search button, and then type in a valid Pokemon name–I get the following error message: TypeError: Cannot read properties of null (reading ‘style’)

However, it does work in the other direction i.e. first typing in a valid Pokemon name, and then typing in an invalid one or first typing in a valid Pokemon name, and then leaving the input blank and pressing the search button.

I think the problem is, when I go in the direction in which it doesn’t work, I am trying to do things with data that I don’t have yet. So I think I almost need a render type function that resets the app and retrieves all the data again but so far I’ve tried everything I can think of and haven’t been able to figure it out!

Would appreciate any help! :slight_smile:

OK, so here you need to think about the HTML.

Look at your HTML structure. Look at the ways you CHANGE that html structure in your code. Remember: you can only set the innerHTML of an element that exists. Are you inadvertently destroying an element you want to keep?

I’m stumped! I’ve been looking at it for a while now and don’t know how to fix it.
Even though I get the error I see that the data is coming through which is good–it just isn’t appearing on the screen. innerContainer, pokemonSnapshot and PokemonStats are all from HTML elements that exist in my html file so I’m not sure which one or how I am destroying it.

What’s hard-coded in your HTML file when the page loads can still be changed by your JS.

Consider this HTML:

<div id="intro">
  <p id="p1">This is text 1</p>
  <p id="p2">This is text 2</p>
</div>

Next I will take control of the div

const div1 = document.getElementById('intro')

And I will empty it’s innerHTML

div1.innerHTML = ''

And now I will try to take control of the p tag with the id p1

const p1 = document.getElementById(‘p1’)`

And I get an error! Because when I update the innerHTML of the div I change all of the HTML in that div! So the p tag with an id of p1 no longer exists even though it’s in my html.

Thank you so much Tom! I got it working!

1 Like

Excellent!!! Nice work and nice design!!