app 엘리먼트를 담을 container 변수생성
보여줄 포켓몬 최대 수를 지정하는 pokemons 변수 생성
IPokemon - 우리가 api에서 가져올 포켓몬 객체 형식을 지정하는 인터페이스 생성
포켓몬 정보를 불러오는 getPokemon 함수를 100번 실행시킬 fetchData 함수 구현
인자값으로 1~100 값을 받고 포켓몬 api를 요청하고 데이터를 가공 한 후(getPokemon) html에 포켓몬 card를 추가하는 showPokemon 함수 구현
fetchData 실행
tsc 명령어로 app.ts => app.js 변환 후 결과 확인!
// getElementById를 사용했을때 리턴값이 둘 중 하나로 자동으로 추론함. 그래서 안써줘도 무관
const container: HTMLElement | null = document.getElementById("app");
const pokemons: number = 100;
// 가져올 데이터 형식
interface IPokemon {
id: number;
name: string;
image: string;
type: string;
}
// 가져올 데이터 수만큼 getPokemon함수를 실행시켜줄 함수생성
const fetchData = (): void => {
for (let i = 1; i <= pokemons; i++) {
getPokemon(i);
}
};
// 비동기처리위해서 async함수를 사용 => return값에 promise사용
const getPokemon = async (id: number): Promise<void> => {
const data: Response = await fetch(`https://pokeapi.co/api/v2/pokemon/${id}`);
// json형태로 한 번 더 가공필, 데이터가 너무 많아서 any타입사용
const pokemon: any = await data.json();
const pokemonType: string = pokemon.types
// 타입이 여러개인 경우가 있어서
.map((poke: any) => poke.type.name)
.join(", ");
const transformedPokemon: IPokemon = {
id: pokemon.id,
name: pokemon.name,
image: `${pokemon.sprites.front_default}`,
type: pokemonType,
};
showPokemon(transformedPokemon);
};
const showPokemon = (pokemon: IPokemon): void => {
let output: string = `
<div class="card">
<span class="card--id">#${pokemon.id}</span>
<img class="card--image" src=${pokemon.image} alt=${pokemon.name} />
<h1 class="card--name">${pokemon.name}</h1>
<span class="card--details">${pokemon.type}</span>
</div>
`;
// container의 type이 null일수도 있기때문에 null이 아닐경우에만 넣어주도록 지정
if (container) {
container.innerHTML += output;
}
};
fetchData();
+++이렇게 실행하면 id가 뒤죽박죽으로 순서가 나옴! fetchData에 비동기처리를 해줘야 함!!
const fetchData = async (): Promise<void> => {
for (let i = 1; i <= pokemons; i++) {
await getPokemon(i);
}
};