Help with proper implementation of fetch API

Hie guys, so I have just recently learned about dealing with APIs and decided to create a dog gallery that uses fetch to get data from an API.

Problem is, even though the app works, I have doubts of whether am following best practice because I am nesting the fetch request inside loops which I think might affect performance. Can some please advice or suggest a better way to do this.

// container is a ul element with 12 generated li items
// createListItem creates a li with a dog image and a breed h2
// These functions respond to search and random button clicks
function generateDogList(breed = 'affenpinscher') {
  container.innerHTML = '';
  for (let i = 0; i < 12; i++) {
    fetch(`https://dog.ceo/api/breed/${breed}/images/random`)
      .then(res => res.json())
      .then(img => {
        createListItem(img.message, breed);
      });
  }
}

function randomBreeds() {
  container.innerHTML = '';
  for (let i = 0; i < 12; i++) {
    fetch(`https://dog.ceo/api/breeds/list`)
      .then(res => res.json())
      .then(data => {
        let randomBreed =
          data.message[Math.floor(Math.random() * (data.message.length - 1))];
        fetch(`https://dog.ceo/api/breed/${randomBreed}/images/random`)
          .then(res => res.json())
          .then(img=> {
            createListItem(img.message, randomBreed);
          });
      });
  }
}

For the generateDogList function you can use the “multiple images from a breed collection” endpoint.

https://dog.ceo/api/breed/${breed}/images/random/12

For randomBreeds you do not need to fetch the breeds list more than one time (save it before the loop). But if you want 12 random different breed images I guess you do have to make that many requests. It might be easier to just use the random image endpoint though.

I’d suggest looking into using async/await (longer article).

1 Like

Thanks a lot for the awesome suggestions

  1. I didn’t know that endpoint existed, learnt to study my APIs next time
  2. I decided to use the random dog endpoint like you suggested and split the url to get the breed name like this
function randomBreeds() {
  container.innerHTML = '';
  for (let i = 0; i < 12; i++) {
    fetch('https://dog.ceo/api/breeds/image/random')
      .then(res => {
        if (!res.ok) {
          throw Error(res.statusText);
        }
        return res.json();
      })
      .then(data => {
        let breed = data.message.split('/')[4];
        createListItem(data.message, breed);
      });
  }
}
  1. As we speak, am looking into async/await and trying to wrap my head around refactoring it t use in my code.