30 Days Of JavaScript

Day 27: Making A PokeDex: Day 2

Lesson 3: PokeDex 7

Now we have somewhere to get our data from it's time to show the modal.

Add this function:

1const showModal = (pokemonId) => {
2  modalTitle.innerText = pokemonArray[pokemonId - 1].name;
3  modalImage.src = pokemonArray[pokemonId - 1].sprites.front_default;
4
5  modalBackdrop.classList.remove("hidden");
6};

Then in addCard assign it to the onclick event handler for the card right before adding it to the DOM:

1newCard.onclick = () => showModal(pokemon.id);

Just to remind you. Event handlers want a function to execute later. We can't just do this newCard.onclick = showModal as our showModal function needs the id for the Pokemon. So we create an arrow function that will call showModal() with the Pokemon id (() => showModal(pokemon.id);) and we then set that arrow function as the event handler.

Now when you click on a Pokemon, a modal pops up with the name and a larger picture.

The data for that modal is coming from pokemonArray and we are able to use the Pokemon id to get it straight from the array. We need to subtract 1 from the id though because the first pokemon has an id of 1 and the array index starts are 0.

This isn't a very reliable way of doing this though.

We are assuming that all Pokemon ids are sequential, if one of them skips or is missing this approach fails.

We have two approaches we can use here:

  1. We can use array.find and find the Pokemon we want. As the number of Pokemon grows this could become slow though.
  2. We could change how we store the data, rather than an array, we use an object where the key is the id of the Pokemon. This will be fast as our list grows but means we have to change how we save the data.

In this case I want you to get used to using the find() method so we are just going to do it that way, there are around 1,000 Pokemon so it will never be that slow anyway!

Change your showModal function to this:

1const showModal = (pokemonId) => {
2  const foundPokemon = pokemonArray.find((p) => p.id === pokemonId);
3
4  modalTitle.innerText = foundPokemon.name;
5  modalImage.src = foundPokemon.sprites.front_default;
6
7  modalBackdrop.classList.remove("hidden");
8};

That's much more robust, now the id can be anything and it won't matter.

Let's dismiss this modal, and go back to our old friend currentTarget vs target.

We will make it so clicking on the background dismisses the modal, but not clicking inside the modal.

Add this function:

1const dismissModal = (e) => {
2  if (e.currentTarget === e.target) {
3    modalBackdrop.classList.add("hidden");
4  }
5};
6
7modalBackdrop.onclick = dismissModal;

Remember that because modal is a child of backdrop we need to make sure that the event that caused the event handler to fire, is the same one that the event handler is actually attached to. If we didn't do this check then clicking on any child node of backdrop will cause the event to fire.

Outline

Go Pro?

If you upgraded to pro, sign in here

  • About
  • Blog
  • Privacy
Looking to email me? You can get me on my first name at allthecode.co