Search code examples
javascriptfetch-api

How do I get images to refresh when clicking a button


I am in an intro JS class and we are using APIs to create a web page. A user is supposed to select an option from the drop down menu, click the button and have information and pictures populated onto the screen.

I have it to where the information refreshes with every click, I just cannot get the pictures to refresh. They are just piling on to the next. I am looking for some type of loop maybe? to help refresh the pictures. I can show more code if necessary, I just figured these two functions were the problem functions.

Code Snippet

window.onload = () => {
  fetchBreeds();
  const button = document.querySelector("#breed-info");
  button.onclick = loadBreed;
}

async function fetchBreeds() {
  const url = 'https://api.thecatapi.com/v1/breeds';
  const config = {
    method: "get",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "<api-key>"
    }
  }
  const response = await fetch(url, config);
  const data = await response.json();

  breedName(data);

}

async function loadBreed() {
  const breeds = document.querySelector("#breeds");
  const url =
    `https://api.thecatapi.com/v1/breeds/${breeds.value}`;
  const config = {
    method: "get",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "<api-key>"
    }
  }
  const response = await fetch(url, config);
  const data = await response.json();
  breedInfo(data);
  loadImages(data);
}

async function loadImages() {
  const breeds = document.querySelector("#breeds");
  const url = `https://api.thecatapi.com/v1/images/search?limit=10&breed_ids=${breeds.value}`;
  const config = {
    method: "get",
    mode: "cors",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": "<api-key>"
    }
  }
  const response = await fetch(url, config);
  const data = await response.json();
  showCat(data);
}

function showCat(data) {
  const catArea = document.querySelector("#bottom");
  for (let catRecord of data) {
    const image = document.createElement("img");
    image.src = catRecord.url;
    catArea.appendChild(image);

  }
  catArea.removeChild(image);
}

function breedName(data) {
  const breeds = document.querySelector("#breeds");
  for (let list of data) {
    const catName = list.name;
    let catID = list.id;
    //console.log(catID);
    breeds.innerHTML += `<option value = "${catID}">${catName}</option`;
  }
}

function breedInfo(data) {
  const name = data.name;
  const describe = data.description;
  const origin = data.origin;
  const lifeSpan = data.life_span;
  let kidFriendly = data.child_friendly;
  let dogFriendly = data.dog_friendly;
  let energy = data.energy_level;
  let social = data.social_needs;
  const learn = data.wikipedia_url;

  if (kidFriendly == 1) {
    kidFriendly = "very unfriendly (1)";
  } else if (kidFriendly == 2) {
    kidFriendly = "unfriendly (2)"
  } else if (kidFriendly == 3) {
    kidFriendly = "indifferent (3)"
  } else if (kidFriendly == 4) {
    kidFriendly = "friendly (4)"
  } else if (kidFriendly == 5) {
    kidFriendly = "very friendly (5)"
  }


  if (dogFriendly == 1) {
    dogFriendly = "very unfriendly (1)";
  } else if (dogFriendly == 2) {
    dogFriendly = "unfriendly (2)"
  } else if (dogFriendly == 3) {
    dogFriendly = "indifferent (3)"
  } else if (dogFriendly == 4) {
    dogFriendly = "friendly (4)"
  } else if (dogFriendly == 5) {
    dogFriendly = "very friendly (5)"
  }

  if (energy == 1) {
    energy = "like a slot (1)";
  } else if (energy == 2) {
    energy = "slow moving(2)"
  } else if (energy == 3) {
    energy = "energetic (3)"
  } else if (energy == 4) {
    energy = "a ball of energy (4)"
  } else if (energy == 5) {
    energy = "bouncing of the walls (5)"
  }

  if (social == 1) {
    social = "antisocial (1)";
  } else if (social == 2) {
    social = "a loner (2)"
  } else if (social == 3) {
    social = "indifferent (3)"
  } else if (social == 4) {
    social = "needs friends (4)"
  } else if (social == 5) {
    social = "very needy (5)"
  }


  document.querySelector("#name").innerHTML = `<span id="name">${name}</span>`;
  document.querySelector("#description").innerHTML = `<span id="description">${describe}</span>`;
  document.querySelector("#origin").innerHTML = `<span id="origin">${origin}</span>`;
  document.querySelector("#life-span").innerHTML = `<span id="life-span">${lifeSpan} years</span>`;
  document.querySelector("#child-friendly").innerHTML = `<span id="child-friendly">${kidFriendly}</span>`;
  document.querySelector("#dog-friendly").innerHTML = `<span id="dog-friendly">${dogFriendly}</span>`;
  document.querySelector("#energy-level").innerHTML = `<span id="energy-level">${energy}</span>`;
  document.querySelector("#social-needs").innerHTML = `<span id="social-needs">${social}</span>`;
  document.querySelector("#wiki").innerHTML = `<a id="wiki" href="${learn}">${learn}</a>`;
}
<section id="left">
  <h1>Breeds</h1>

  <select id="breeds">

  </select>

  <button id="breed-info">Explore cat breed!</button>
</section>

<section id="right">
  <p><label>Name:</label> <span id="name"></span></p>
  <p><label>Description:</label> <span id="description"></span></p>
  <p><label>Origin:</label> <span id="origin"></span></p>
  <p><label>Life span:</label> <span id="life-span"></span></p>
  <p><label>Child friendly:</label> <span id="child-friendly"></span></p>
  <p><label>Dog friendly:</label> <span id="dog-friendly"></span></p>
  <p><label>Energy level:</label> <span id="energy-level"></span></p>
  <p><label>Social needs:</label> <span id="social-needs"></span></p>
  <p><label>Learn more:</label>
    <a id="wiki" href="#"></a>
  </p>
</section>

<section id="bottom">

</section>


Solution

  • When you call showCat you just keep appending children:

    const catArea = document.querySelector("#bottom");
    for (let catRecord of data) {
        const image = document.createElement("img");
        image.src = catRecord.url;
        catArea.appendChild(image);
    
    } 
    

    Sounds like you just need to clear the catArea first - you could do catArea.innerHTML = '', or you can use catArea.replaceChildren, e.g.:

    const catArea = document.querySelector("#bottom");
    const images = data.map(catRecord => {
        const image = document.createElement("img");
        image.src = catRecord.url;
        return image;
    })
    catArea.replaceChildren.apply(catArea, images);
    

    Runnable example (using text):

        const data = [{url: 'C'}, {url: 'D'}]
        const catArea = document.querySelector("#bottom");
        const replacements = data.map(catRecord => {
            const image = document.createElement("span");
            image.innerHTML = catRecord.url;
            return image;
        });
        catArea.replaceChildren.apply(catArea, replacements)
    <div id="bottom"><span>A</span><span>B</span></div>