FE 프로젝트

[개인 미니 프로젝트] PokeAPI로 포켓몬 도감 만들기 (2) 1일차 - API 얻어오기

바닷가쟤 2023. 9. 6. 01:13

1일차인 09.05(화)에는 API를 가져와서 콘솔에 출력하는게 목표다.

API를 내 힘으로 가져와서 사용해본 적이 없어서 조금 걱정 + 막막하기도 했다.

다사다난한... API 사용하는걸 본 적은 있어도 어떻게 찾고 어떻게 적용하는지는 잘.. 모르는 나...

어렵다...

하지만 이번에 챗 지피티 센세의 도움을 많이 받긴 했지만 비동기를 많이 사용하는구나.. 어떻게 사용하는구나.. 를 알게 되어서 나름 얻어간게 있는 것 같다 !

이런 지식과 경험이 차곡차곡 쌓여서 실력이 될거라고 믿을거다.

걱정하기 전에 하나라도 더 보고 쳐보자..


1일차 성과

- 프로젝트 계획을 짰다. 어떤 기능을 구현할건지 정해놓고 마음도 다시 단단히 먹었다.
- API를 가져와서 console에 원하는 데이터 출력에 성공했다.

Poke API 뜯어보기

https://pokeapi.co/docs/v2

 

Documentation - PokéAPI

If you were using v1 of this API, please switch to v2 (this page). Read more… Quick tip: Use your browser's "find on page" feature to search for specific resource types (Ctrl+F or Cmd+F). Information This is a consumption-only API — only the HTTP GET m

pokeapi.co

이걸 나름 읽는다고 읽었지만 솔직히 아무것도 모르고 경험 없는 내가 보기엔... @@@(머리 터짐)

그래서 Poke API를 사용해서 무언가를 만든 사람들 블로그를 참고하면서 아하... ㅎ 하고 일단 vs코드를 켜고 뭔가를 뚱땅뚱땅 쳐봤다.

그러면서...

https://pokeapi.co/api/v2/pokemon?limit=150

이 링크로 비동기 함수를 써서 json어쩌구를 하면 데이터를 받을 수 있을 것 같다.

포켓몬 리스트포켓몬의 키/몸무게를 받아오는데 사용했다.

참고로 limit=150은 일단 1000마리가 넘는 포켓몬 중 150번째까지만 받아오겠다는 제한이다. (나중에 제한 풀 생각)

 

https://pokeapi.co/api/v2/pokemon-species

이것도 사용했다. 포켓몬의 상세 정보를 얻을 수 있다.

한국어 이름과 정보가 여기 있어서 이걸 사용했다^-^

pokemon-species

species에서 n번째 포켓몬을 클릭해서 보면 이렇게 나오는데, names의 3번째(제로베이스 넘버링은 2)가 한국어다.

그래서 names[3].name으로 구해오면 된다.

 

 

https://pokeapi.co/api/v2/type/

여기서 type별 pokemon을 얻어올 수 있을 것 같다(그렇긴 한데 내 프로젝트에 적용시킬 수 있을진 모르겠다....)

 


API 가져오기 시도

여러 시도를 해봤다.

https://youtu.be/I5ty-nwO7as?si=qc7ozktU3bpvysKW 

처음에는 이 영상을 참고했다.

하지만 이번 프로젝트 목표는 따라치기가 아닌 내가 직접 만들면서 배우는거라서 최소한 api 사용법만 빼먹었다.

(2편까지 띄엄띄엄 봤다)

 

다른 잘 만든 사람 블로그를 보고 깃허브를 뜯어보면서 이해해보려고 했다.

axios를 이렇게 쓰는거구나 알게 되어서 좋았다.

하지만..^^ 어떻게 활용하는건진 몰라서 실패 ..ㅎ 전에 계속 하던 방식대로 하기로 했다.

 

지피티 선생님과 많은 대화 끝에 console에 내가 원하는 값을 다 출력할 수 있었다.

이런 늑김이랍니다

코드는 정말 더럽다..... 한숨이 나온다 ...ㅎ.ㅋ.ㅋ.ㅋ.

정리하고 싶은데 손을 못 댈 것 같다....하핳.ㅎ..ㅎㅎ...

일단 만드는데 의의를 두자고


코드

- index.html
- main.js
- pokeApi.js

 

main.js

import { fetchPokemon } from "./pokeApi";

const loadData = async () => {
  try {
    const data = await fetchPokemon();
    // 데이터가 로드된 후에 이 부분에서 데이터를 사용할 수 있음
    console.log(data[10]);
    console.log(data[10].type);
  } catch (error) {
    console.error("오류 발생:", error);
  }
};

loadData();

 

pokeApi.js

export const fetchPokemon = async () => {
  return new Promise(async (resolve, reject) => {
    const arrPokemon = [];

    const fetchNums = 150;
    const url = `https://pokeapi.co/api/v2/pokemon?limit=${fetchNums}`;

    // species 한국어 이름, 종, 설명
    const urls = []; // species api 포켓몬별 url
    const koreanNames = []; // 포켓몬 한국어 이름
    const genus = []; // 포켓몬 종
    const flavorText = []; // 포켓몬 짧은 요약
    const types = []; // 포켓몬 타입

    for (let i = 0; i < fetchNums; i++) {
      let url = `https://pokeapi.co/api/v2/pokemon-species/${i + 1}`;
      urls.push(url);
    }

    let requests = urls.map((url) => fetch(url));

    // 비동기 작업을 여기서 기다림
    await Promise.all(requests)
      .then((responses) =>
        Promise.all(responses.map((res) => res.json())).then((results) => {
          for (let result of results) {
            if (result.egg_groups[1]) {
              types.push([
                result.egg_groups[0].name,
                result.egg_groups[1].name,
              ]);
            } else {
              types.push(result.egg_groups[0].name);
            }
            koreanNames.push(result.names[2].name);
            genus.push(result.genera[1].genus);
            flavorText.push(result.flavor_text_entries[23].flavor_text);
          }
        })
      )
      .catch((error) => {
        console.error("오류 발생:", error);
        reject(error); // 실패 시 reject 호출
      });

    // 개별 포켓몬 정보를 가져오는 함수
    const fetchIndividualPokemon = async (index) => {
      const individualUrl = `https://pokeapi.co/api/v2/pokemon/${index + 1}`;
      const individualRes = await fetch(individualUrl);
      const individualData = await individualRes.json();
      return {
        height: individualData.height,
        weight: individualData.weight,
      };
    };

    // 개별 포켓몬 정보를 가져오는 비동기 작업을 수행하고 기다림
    const individualPokemonData = await Promise.all(
      Array.from({ length: fetchNums }, (_, index) =>
        fetchIndividualPokemon(index)
      )
    );

    // 데이터를 사용하는 부분
    const res = await fetch(url);
    const data = await res.json();

    const loadedPokemon = data.results.map((pokemon, index) => {
      return {
        name: koreanNames[index],
        id: index + 1,
        gif: `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/versions/generation-v/black-white/animated/${
          index + 1
        }.gif`,
        image: `https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${
          index + 1
        }.png`,
        genera: genus[index],
        text: flavorText[index],
        type: types[index],
        height: individualPokemonData[index].height,
        weight: individualPokemonData[index].weight,
      };
    });

    arrPokemon.push(...loadedPokemon);

    resolve(arrPokemon); // 비동기 작업이 완료되면 resolve 호출
  });
};

정신 없는...정체불명의 코드...

다른 사람들이 보면 뭔... 저게 뭐니...왜 저렇게 하지 이렇게 간단히 뿅 하면 되는걸.. 할 수도 있지만..

어케하는지 모르겟숴요ㅣ.. 일단 어거지로 만들어 놓긴 한고ㅓ....

api 입문기 참 어렵따.

 

답답했던건 사용법은 매우 대충 띡 나와있고 대체 export import는 어떻게 하며 어떻게 데이터를 받아서 써야하는건지를 모르겠다

그런 개념이 아직 잡혀있지 않아서 ...

근데 그걸 알면 취업해야지 안그려? 

무튼 기죽지 말고 계속 열심히 해보자.


내일 할 일

- 메인 페이지 구현 : 화면에 포켓몬 출력하기
- css 디자인 하기
- 서브 페이지 구현 : 포켓몬 상세 정보 페이지 (라우팅 기능)
- 추가 기능 정보 구글링하기
- (시간 되면) 찜하기 기능 구현하기

3일 짧으니까 매일 블로그를 쓰려고 한다(아니 써야 한다 열심히 해라 주인장)

728x90