Flipping cards to show new InnerHTML

I am working on a Pokedex using the PokeAPI to display Pokemon cards (see below)

I want to be able to click on the cards to flip them over and display new data. However I am having a lot of trouble with this. I am not sure how to call the “card back” information and InnerHTML and my Javascript flip function isn’t working.

document.addEventListener('turbolinks:load', () => {
  const poke_container =
  document.getElementById('poke_container');
  const dex_id = 151;
  const colors = {
    grass: '#63BB5B',
    fire: '#FF9C54',
    water: '#4E90D5',
    electric: '#F3D23B',
    ice: '#74CEC0',
    poison: '#AB6AC8',
    ground: '#D97746',
    rock: '#C7B78B',
    bug: '#90C12C',
    dragon: '#0A6DC4',
    normal: '#f9199A1',
    flying: '#8FA8DD',
    fighting: '#D80A49',
    psychic: '#F97176',
    ghost: '#5269AC',
    dark: '#5A5366',
    steel: '#5A8EA1',
    fairy: '#EC8FE6',
  };

  const main_types = Object.keys(colors);


  const fetchPokemon = async () => {
    for (let i = 1; i<= dex_id; i++) {
      await getPokemon(i);
    }
  };

  const getPokemon = async id => {
    const url = `https://pokeapi.co/api/v2/pokemon/${id}`;
    const res = await fetch(url);
    const pokemon = await res.json();
    createPokemonCard(pokemon);

  };

  fetchPokemon();

  function createPokemonCard(pokemon) {
    const pokemonEl = document.createElement('div');
    const pokemonElBack = document.createElement('div');
    pokemonEl.classList.add('pokemon');
    const poke_types = pokemon.types.map(el => el.type.name);
    const type = pokemon.types[0].type.name;
    //const stats = pokemon.stats[0].stat.name;
    const ability = pokemon.abilities[0].ability.name;
    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>
      <a href="https://bulbapedia.bulbagarden.net/wiki/${name}_(Pok%C3%A9mon)" class="name"><h3>${name}</h3></a>
      <small class="type"><span>${type.charAt(0).toUpperCase() + type.slice(1)}</span></small>
    </div>
    `;

    pokemonEl.innerHTML = pokeInnerHTML;

    poke_container.appendChild(pokemonEl);


  const pokeCardBack = `
    <div class="flipped">
      <div class="img-container">
      <img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/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"><span>${ability}</span></small>
      </div>
    </div>
    `;

    pokemonElBack.innerHTML = pokeCardBack;

    const back = document.querySelectorAll('.pokemon');

    function flipCard() {
      this.classList.toggle('flipped');
    }
    back.forEach((card) => card.addEventListener("click", flipCard));


}});

Everything is ok until my pokeCardBack function which isn’t displaying.

In CSS I just have:

.pokemon .flipped {
  transform: rotateY(180deg);
}

How can I display different data for the card back inside my Javascript function?

You might consider commenting in the code to make what you’re trying to do clear. Like:

//load cards from API

//uses animation to “flip” cards

etc…

Next, when you say this particular function isn’t working, is it not working in the context of the whole program, or is that particular function itself not working? Have you broken the individual components out and made sure they all work before stringing them together in this large callback function?

Your back variable holds all elements with class .pokemon, and with their event listeners, you add the class .flipped, so in your CSS you’d have to target them with

.pokemon.flipped {
  transform: rotateY(180deg);
}

(remove the space in the selector).

I added in some notes to make it more clear.

document.addEventListener('turbolinks:load', () => {
  const poke_container =
  document.getElementById('poke_container');
  const dex_id = 151;
  const colors = {
    grass: '#63BB5B',
    fire: '#FF9C54',
    water: '#4E90D5',
    electric: '#F3D23B',
    ice: '#74CEC0',
    poison: '#AB6AC8',
    ground: '#D97746',
    rock: '#C7B78B',
    bug: '#90C12C',
    dragon: '#0A6DC4',
    normal: '#f9199A1',
    flying: '#8FA8DD',
    fighting: '#D80A49',
    psychic: '#F97176',
    ghost: '#5269AC',
    dark: '#5A5366',
    steel: '#5A8EA1',
    fairy: '#EC8FE6',
  };
//Fetch card colors
  const main_types = Object.keys(colors);

//Get Pokemon from API
  const fetchPokemon = async () => {
    for (let i = 1; i<= dex_id; i++) {
      await getPokemon(i);
    }
  };

  const getPokemon = async id => {
    const url = `https://pokeapi.co/api/v2/pokemon/${id}`;
    const res = await fetch(url);
    const pokemon = await res.json();
    createPokemonCard(pokemon);

  };

  fetchPokemon();

//Variables for Pokemon Card data from API
  function createPokemonCard(pokemon) {
    const pokemonEl = document.createElement('div');
    const pokemonElBack = document.createElement('div');
    pokemonEl.classList.add('pokemon');
    const poke_types = pokemon.types.map(el => el.type.name);
    const type = pokemon.types[0].type.name;
    //const stats = pokemon.stats[0].stat.name;
    const ability = pokemon.abilities[0].ability.name;
    const name = pokemon.name[0].toUpperCase() + pokemon.name.slice(1);
    const card_color = colors[type];

    pokemonEl.style.backgroundColor = card_color;

    //Card Front data and HTML
    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>
      <a href="https://bulbapedia.bulbagarden.net/wiki/${name}_(Pok%C3%A9mon)" class="name"><h3>${name}</h3></a>
      <small class="type"><span>${type.charAt(0).toUpperCase() + type.slice(1)}</span></small>
    </div>
    `;

    pokemonEl.innerHTML = pokeInnerHTML;

    poke_container.appendChild(pokemonEl);

// Back of the card data
  const pokeCardBack = `
    <div class="flipped">
      <div class="img-container">
      <img src="https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/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"><span>${ability}</span></small>
      </div>
    </div>
    `;

    pokemonElBack.innerHTML = pokeCardBack;

    //Flip card from front to back function
    const back = document.querySelectorAll('.pokemon');

    function flipCard() {
      this.classList.toggle('flipped');
    }
    back.forEach((card) => card.addEventListener("click", flipCard));


}});

I fixed the CSS so to .pokemon.flipped, but now when it flips the card it just reverses the text instead of display my card back data, and it only works for every other card.