A Vanilla javascript project using dog api (Part-3)

This blog is a part of a blog series to make a vanilla js project using the Dog Api to show beginners how to use an API .Please check the first and second part if you haven’t already.

Overview

Now that you have learned how to fetch a list of dog breeds, let’s show some images of each dog breed when selected from the list.

Pre-requisites

  • Basic HTML
  • Basic CSS
  • Basic understanding of Javascript variables and functions
  • Basic understanding of DOM (document object)
  • Fetch Api (Javascript)
  • Promises (Javascript)

Let’s Begin

If you check the documentation of the dog api then you will notice there’s a section for the Breed Images . You can see that the API (url) to get the list of images is https://dog.ceo/api/breed/hound/images . If you click this url you will get something like this in the browser:

{
    "message": [
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_1003.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_1007.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_1023.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_10263.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_10715.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_10822.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_10832.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_10982.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_11006.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_11172.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_11182.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_1126.jpg",
        "https://images.dog.ceo/breeds/hound-afghan/n02088094_1128.jpg"
    ]
}

To get the images for different breeds, we only need to replace the “hound” with the respective breed name .

As you can see in the above json response, our image list is saved in the “message” field. We will use this information in the javascript .

HTML

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <link rel="stylesheet" href="style.css">

</head>
<body>

  <!-- we will add breed names as <li> tag from js-->
  <ul id="ul_breeds">
  </ul>

  <div id="img_container">
  </div>

  <script src="main.js"></script>
  
</body>
</html>

As you can see, we only added a new div with id = img_container . We will add our images in this div from javascript.

CSS

*{
  box-sizing: border-box;
}
body{
  padding: 0px;
  margin: 0px;
}



#ul_breeds{
  list-style-type: none;
  padding: 0px;
  margin: 0px;
  width: 200px;
  background-color: #f5f7f9;
  position: absolute;
}
#ul_breeds li{
  padding: 10px;
}
#ul_breeds li:hover{
  padding: 10px;
  background-color: #d5d7d9;
}



/*
  part-3 styles
*/
#img_container{
  padding-left: 200px;
  width: 100%;
  min-width: 100px;
  text-align: center;
}

.gridItem{
  width: 200px;
  height: 200px;
  margin-left: 1%;
  margin-top: 1%;
  display: inline-block;
  object-fit: cover;
  transition: transform 0.3s;
}
.gridItem:hover{
  transform: scale(2, 2);
  object-fit: contain;
}

We only added some basic styles for our elements. Breed names list is like a left column and our image container is right column. We also added some transform animations when you hover on images which you’ll see below. If you wanna know more about css transform and transition, check this section on w3 schools.

Javascript

Now the magical part. We are building upon the previous blog therefore the code also include the functions we made in previous blog.

//we saved the <ul> element in a global variable so we can use it anywhere in the code
const ul_breeds = document.getElementById("ul_breeds");

// a function which is responsible to fetch data from server and pass it to parseJsonResponse() function
function getDogBreeds(){
  const allBreedsApiUrl = "https://dog.ceo/api/breeds/list/all";

  // we are using fetch api to make rest api calls. you can use axios .
  // we are also using promises here. 
  fetch(allBreedsApiUrl)
    .then(function(response){
      // we get raw response. need to first convert it into json format so we can use the data easily
      return response.json();
    })
    .then(function(json){
      // now we got the json . we can use this to update any data in html 
      console.log(json);

      //we don't want to write everything in callbacks so we gave the responsibility of showing data in html to a seperate function
      parseJsonResponse(json);
    })
    .catch(function(error){
      // if any error occurs like no internet connection then this callback will be called
      console.log(error);
      
    });
}

//a seperate function which is responsible to show the json data in html
function parseJsonResponse(json){

  //get the object containing all the breeds data
  var allBreedsData = json.message;

  // we need only breed names from this object which are actually all the keys of this object
  // so we can use Object.keys(object) function to get a list of all the keys in this object
  var breedsList = Object.keys(allBreedsData);

  //reset all the current items in the list if any
  ul_breeds.innerHTML="";

  //now we can iterate thriugh this list and show all the breed names in a list in html
  // we are using forEach loop. you can also use for loop
  breedsList.forEach(function(breed){
    //we use template literals to generate the html for our single list item
    var listItemHtml = `<li>${breed}</li>`;
    // += is used to keep adding more list items in the list without removing the already available items in the list
    ul_breeds.innerHTML+=  listItemHtml;
  })
}

//call the getDogBreeds function whenever page loads
getDogBreeds();











//////////////////code for part 3 starts here//////////////////////////////////

const img_container = document.getElementById("img_container");

// a function which is responsible to fetch images of a breed. It takes breedname as an argument
function getDogImages(breedName){

  const dogImagesUrl = `https://dog.ceo/api/breed/${breedName}/images`;

  // we are using fetch api to make rest api calls. you can use axios .
  // we are also using promises here. 
  fetch(dogImagesUrl)
    .then(function(response){
      // we get raw response. need to first convert it into json format so we can use the data easily
      return response.json();
    })
    .then(function(json){
      // now we got the json . we can use this to update any data in html 
      console.log(json);

      //we don't want to write everything in callbacks so we gave the responsibility of showing data in html to a seperate function
      showImagesInHtml(json);
    })
    .catch(function(error){
      // if any error occurs like no internet connection then this callback will be called
      console.log(error);
      
    });
}
//this functions just takes the json response from the fetch api and show the data in html
function showImagesInHtml(json){
  var imageList = json.message;
  //reset the current list
  img_container.innerHTML="";
  imageList.forEach(function(image){
    // add the html code for single image in the container
    img_container.innerHTML+= `<img class="gridItem" src="${image}"></img>`
  })
}

ul_breeds.addEventListener("click",function(e){
  // check if we clicked the list items in ul 
  if(e.target && e.target.nodeName == "LI") {
    // after confirming that the click was on a list item, we will call the getDogImages function to refresh the images.
    getDogImages(e.target.innerHTML.trim());
  }
})

Explanation

We made two new functions here getDogImages() and showImagesInHtml() . We also added a click listener to the list so we can refresh the images whenever a breed name is clicked.

As explained above, the images are saved in the message field of the json that’s why we are using json.message to get the images in javascript

var imageList = json.message;

Output

Video Output

All the code is available on github

Congratulations. You have completed this blog series. Please feel free to ask your doubts, if any, in the comments section below.

Leave a Comment

Your email address will not be published. Required fields are marked *