본문 바로가기
Development (국비 복습 )/프로젝트

API로 강아지 사진슬라이드

by Puddingforever 2023. 3. 11.

💡목표

-오픈 API를 이용하여 강아지 슬라이드 웹페이지를 구현한다. 

 

📈 예상효과

-API의 쓰임을 알게된다.

-자바스크립트의 async-await 을 사용하는 법을 알게된다. 

-자바스크립트 비동기 로직을 이해한다.

 

 

🔗관련문서 

https://dog.ceo/dog-api/documentation/ 

 

💭 아키텍처 구성 및 접근방법 계획

1.강아지 종류를 선택할 수 있는 <select>를 이용하여 

API소스의 데이터를 async를 이용하여 받는다. 

2.받아온 데이터를 html로 구현한다.

 

 

API (application programming interface)컴퓨터 사이의 통신을 쉽게 하는 연결해주는 인터페이스

 

[목표]

https://dog.ceo/dog-api/documentation/ 

여기있는 json형식으로 된 강아지 api를 가지고 와서 강아지 사진을 보여주는 홈페이지를 만들것이다.

 

 

 

1.강아지 리스트 만들기

fetch("https://dog.ceo/api/breeds/list/all")

fetch로 api를 가져왔는데, 이 서버가 다 로딩되기 전에 강아지 사진이나 정보들을 보여주고 싶다.

만약 이 서버가 다 로딩된 후 , 서버에 저장된 사진이나 정보들을 보여준다면 시간이 오래걸릴 수도 있다.

이때는 promise를 쓰면 되는데, 기존 promise 방식을 써보자

 

fetch("https://dog.ceo/api/breeds/list/all")
                .then(function(response){  
                return resoonse.json();
                })
                .then(function(data){
                console.log(data);
                })


promise는 then()이라는 메소드를 가지고 있으며 , then()이 실행되면 다음 then()이 실행된다. 

즉 fetch에 들어있는 url이 실행되기 전에 미리 then()을 실행하는 것이다.

하지만 최근에는 더 간단한 표현을 위해 async await 문법을 쓴다. 

async function start(){
	const response = await fetch("https://dog.ceo/api/breeds/list/all");
    const data = await response.json();
    console.log(data);
}

 

async로 start()함수를 비동기화해주고, await 으로 fetch가 실행되면 , 다음 코드가 실행되도록 하였다.

json()을 하는 이유는 url의 response를 받을 때
json()형식으로 정보가 써있기 때문이다.

이렇게 json형식으로 되어있기 때문에 , 데이터를 받을때 .json()화 해준다



function createBreedList(breedList){
document.getElementById("breed").innerHTML =`
	<select>
        <option>Choose a dog breed</option>
        ${Object.keys(breedList).map(function(breed){
        	return `<option>${breed}</option>`
        }),join("")}
    </select>
}

 

Object.keys()는 받아온 모든 객체를 배열 형식으로 만들어준다.

여기서는 위의 breedList로 전달받을걸 볼 수 있다.

전달받은 json 객체를 확인해보자

여기서의 key는 message이고 , value는 객체 형식으로 되어있으며, 그 안에 다시 key 와 [] 배열 값으로 저장되어있다.

${Object.keys(breedList).map(function(breed)){
                return `<option>${breed}</option>`
        }).join("")}

Object.keys(breadList) 는 가져온 객체를 배열로 만든다. 이를 이용하여 함수를 만들건데, map()을 이용할 수 있다. 자바스크립트에서는 모든 배열은 map()객체에 접근 할 수 있도록 한다.map()안에는 함수를 호출할 수 있으며, 이 함수가 실행되면 , keys(breedList) 값을 가져오게 되는 형식이다.

마지막에 join("")을 쓴 이유는 return 값이 ``를 써서 텍스트 형식으로 되어있는데 , 한번에 다 붙이고 싶기 때문이다.

 

리스트 보여주기 완성

 

2.강아지 사진 보여주기 

 

이제 강아지 종류를 선택한 후 , 사진을 보여주는 과정을 만든다.

async function loadByBreed(breed){
if(breed != "강아지 종류 선택"){
const response = await fetch(url);
const data = await response.json();
createSlideShow(data.message);
}}

createSlideshow() 함수를 만들고 인자값으로 data.message를 넣었다.

message는 받는 json 객체의 key값인데, 이걸로 value들을 이용할 수 있다. 

json()을 함으로서 텍스트형태를 객체타입으로 받을 수 있다.

 

 

 

 

이미지가 잘 들어오는지 확인 

function createSlideshow(images){
	console.log(images);
}

배열로 여러 값들이 들어온 것을 볼 수 있다.

 

데이터 받는 작업을 끝냈으니, 실제 html을 구현한다.

function createSlideshow(images) {
  let currentPosition = 0
  if (images.length > 1) {
    document.getElementById("slideshow").innerHTML = `
  <div class="slide" style="background-image: url('${images[0]}')"></div>
  <div class="slide" style="background-image: url('${images[1]}')"></div>
  `
   currentPosition += 2;
  if (images.length == 2) currentPosition = 0
  } else { 
    document.getElementById("slideshow").innerHTML = `
  <div class="slide" style="background-image: url('${images[0]}')"></div>
  <div class="slide"></div>`
  }

함수 이름은 createSlideShow이며 아까 await으로 사진 데이터를 받아왔다.

사진이 1장 이상일 경우와 한장만 있는 경우를 나눈다. 만약 1장 이상인 경우 , html에 사진[0]을 보여줄건데, 저렇게 두개를 쓴 이유는 fade효과를 주기 위해 작성한 것이다.

css에 slide를 opacity:0; 으로 주고 , slide:nth-last-child(2)는 opacity:1을 주었다. 

nth-last-child(2)는 요소에서 두번째의 요소를 적용하기 때문에 {images[0]}과 {images[1]}이 있다면 , 마지막에서 두번째니까 , image[0]은 보이고, image[1]은 안보이게 된다. 

만약 사진이 정확히 2장만 있다면, [2]가 되면 out of index이기 때문에 0으로 설정해준다.

사진이 하나만 있는 경우는 image[0]만 보여준다.

 

function createSlideshow(images) {
  let currentPosition = 0
  clearInterval(timer)
  clearTimeout(deleteFirstPhotoDelay)
  if (images.length > 1) {
    document.getElementById("slideshow").innerHTML = `
  <div class="slide" style="background-image: url('${images[0]}')"></div>
  <div class="slide" style="background-image: url('${images[1]}')"></div>
  `
   currentPosition += 2; 
  if (images.length == 2) currentPosition = 0
  timer = setInterval(nextSlide, 3000)
  } else {
    document.getElementById("slideshow").innerHTML = `
  <div class="slide" style="background-image: url('${images[0]}')"></div>
  <div class="slide"></div>
  `
  }
  function nextSlide() {
    document.getElementById("slideshow").insertAdjacentHTML("beforeend", `<div class="slide" style="background-image: url('${images[currentPosition]}')"></div>`)
    deleteFirstPhotoDelay = setTimeout(function () {
      document.querySelector(".slide").remove()
    }, 1000)
    if (currentPosition + 1 >= images.length) {
        currentPosition = 0;
    } else {
      currentPosition++;
    }
  }
}

timer = setInterval(nextSlide,3000)을 함수에 넣어서 3초마다 nextSlide()가 실행될 수 있도록 하며 , 

사진이 계속 추가되지만 1초마다 처음 사진을 삭제해준다.

만약 사진을 다 봤다면 (currentPosition+1>=images.length), currentPosition을 다시 0으로 설정하고 , 아닌 경우는 currentPosition을 계속 증가시킨다. 

 

 

 

 

 

완성

 

 

 

https://gitlab.com/PuddingForever/cutedogs

 

Pudding Jeong / cuteDogs · GitLab

오픈소스 API를 이용한 강아지 리스트 보여주기

gitlab.com

 

 

참고

https://codepen.io/learnwebcode/pen/LYNWQgg

댓글