Using indexOf() with API data is affected by the order of strings in my variable

Viewed 38

I'm making a Pokedex using an API that has information on each Pokemon. Some Pokemon have two types, but for now I am just showing their first (main) type. So if they are grass/poison type, I am just showing grass. The background color of the card for each Pokemon is also tied to their main type.

Example:

const colors = {
    grass: '#63BB5B',
    fire: '#FF9C54',
    water: '#4E90D5',
    electric: '#F3D23B',
    ice: '#74CEC0', //etc.
};
const main_types = Object.keys(colors);

However, I noticed that if their main type comes after their secondary type in my colors variable, it will list their secondary type instead along with the color. For example, poison is listed before bug, so all bug/poison type show poison as their main type.

Here's my function (main_types is in the above code):

function createPokemonCard(pokemon) {
    const pokemonEl = document.createElement('div');
    pokemonEl.classList.add('pokemon');
    const poke_types = pokemon.types.map(el => el.type.name);
    const type = main_types.find(mt => poke_types.indexOf(mt) > -1);
    const name = pokemon.name[0].toUpperCase() + pokemon.name.slice(1);
    const card_color = colors[type];

    pokemonEl.style.backgroundColor = card_color;

    const pokeInnerHTML = `
    <div class="img-container">
    <img src="https://pokeres.bastionbot.org/images/pokemon/${pokemon.id}.png" />
    </div>
    <div class ="info">
      <span class="number">#${pokemon.id.toString().padStart(3, '0')}</span>
      <h3 class="name">${name}</h3>
      <small class="type">Type: <span>${type.charAt(0).toUpperCase() + type.slice(1)}</span></small>
    </div>
    `;

    pokemonEl.innerHTML = pokeInnerHTML;

    poke_container.appendChild(pokemonEl);
  }

How can I have my function select their first type regardless of the order in the colors variable?

2 Answers

this will do , you just needed to switch order const type = poke_types.find(mt => main_types.indexOf(mt) > -1);

Array#find searches its elements for the first value satisfying the predicate. So rather than search the main types for the item's types, find the first main type in your item's types.

const myArr = [1, 6, 2, 7];
const ordered = [2, 1];

myArr.find(x => ordered.includes(x)) // 1
ordered.find(x => myArr.includes(x)) // 2
Related