영화 api를 받아서 영화 검색 사이트를 만드는 프로젝트
프로젝트 진행 순서
1. 간단한 와이어 프레임
2. html에 input, button태그와 영화 카드창 생성하기
3. javascript로 기능 구현 : 검색 기능, 홈화면에 모든 영화 정보 띄우는 기능
4. css로 레이아웃 수정하기
3. javascript로 기능 구현 : 검색 기능, 홈화면에 모든 영화 정보 띄우는 기능
홈화면에 모든 영화 정보 띄우는 기능
function movieList(rows) {
rows.map((a) => {
const temp = document.createElement('div');
temp.innerHTML = `<div id="box" onclick="alertId(${a['id']})" style="cursor:pointer;" >
<div class='card'>
<img
src="https://image.tmdb.org/t/p/w500${a['poster_path']}">
<div class='card-title'>${a['title']}</div>
<p class='card-overview'>${a['overview']}</p>
<p>${a['vote_average']}</p>
</div>
</div>`;
document.querySelector('.movie-list').append(temp);
});
}
fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options)
.then((response) => response.json())
.then((response) => {
let rows = response['results'];
movieList(rows);
})
.catch((err) => console.error(err));
문제 해결 순서
1. fetch로 받아온 정보를 rows에 results값만 담기
2. map을 이용해 배열을 하나씩 돌면서 카드형식의 html 만들기 (forEach로도 됨)
알게된 점
document.creatElement(만들고 싶은 html 요소)
해당 함수로 js를 이용해 html 요소를 생성할 수 있는 점을 알게 되었다.
만약에 temp를 div로 만들지 않았을 때에도 innerHTML이 되는지는 모르겠다
해당 방법은 어느 블로그에서 본 것을 토대로 작성한 것이기 때문에 이후에 코드를 작성해서 확인해 보아야 할 것 같다.
검색 기능
function searchMovie() {
const div = document.querySelector('.movie-list');
while (div.firstChild) {
div.removeChild(div.firstChild);
}
let input = document.getElementById('search').value;
fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options)
.then((response) => response.json())
.then((response) => {
let rows = response['results'];
rows.forEach((a) => {
let lowerTitle = a['title'].toLowerCase();
let lowerInput = input.toLowerCase();
if (lowerTitle.includes(lowerInput)) {
const temp = document.createElement('div');
temp.innerHTML = `<div id="box" onclick="alertId(${a['id']})" style="cursor:pointer;">
<div class='card'>
<img
src="https://image.tmdb.org/t/p/w500${a['poster_path']}">
<div class='card-title'>${a['title']}</div>
<p class='card-overview'>${a['overview']}</p>
<p>${a['vote_average']}</p>
</div>
</div>`;
document.querySelector('.movie-list').append(temp);
}
});
});
}
위의 방법과 유사한 방법으로 진행했다.
문제 해결 순서
1. 먼저 모든 영화카드 HTML 삭제
2. 검색 input의 value 값과 fetch로 가져온 데이터 값과 비교
3. 포함되는 글자가 있다면 영화카드 생성
어려웠던 점
- input 값을 받아오는 부분을
let input = document.getElementById('search').value;
fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options)
.then((response) => response.json())
.then((response) => {
let input = document.getElementById('search').value;
})
위의 코드처럼 fetch 함수 안에 작성하게 되면 값이 받아와지지 않는다..!!
이유는 모르겠지만.. 아무래도 fetch 함수가 문제인 것 같아서...
async function fetchMovie() {
let response = await fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options);
let data = await response.json();
// return await data['results'];
console.log(data['results']);
}
이렇게 fetch 데이터를 담는 함수를 만들어서 사용해보고자 했으나
콘솔에 promise { <pending> } 으로 확인된다..!
아무래도 fetch가 promise를 반환하는 함수라서 그런가보다...싶어서
async / await 를 써보고
.then 으로도 해봤지만 결과는 다 똑같았다
그래서 fetch 데이터를 fetch 함수 밖에서 사용하는 것은 포기하고,
serachMovie 함수를 만들어서
함수 내부에서 input의 value를 가져오고,
fetch를 또 실행해서 값을 비교하는 방법으로 진행했다.
function searchMovie() {
const div = document.querySelector('.movie-list');
while (div.firstChild) {
div.removeChild(div.firstChild);
}
let input = document.getElementById('search').value;
fetch('https://api.themoviedb.org/3/movie/top_rated?language=en-US&page=1', options)
.then((response) => response.json())
.then((response) => {
let rows = response['results'];
rows.forEach((a) => {
let lowerTitle = a['title'].toLowerCase();
let lowerInput = input.toLowerCase();
if (lowerTitle.includes(lowerInput)) {
const temp = document.createElement('div');
temp.innerHTML = `<div id="box" onclick="alertId(${a['id']})" style="cursor:pointer;">
<div class='card'>
<img
src="https://image.tmdb.org/t/p/w500${a['poster_path']}">
<div class='card-title'>${a['title']}</div>
<p class='card-overview'>${a['overview']}</p>
<p>${a['vote_average']}</p>
</div>
</div>`;
document.querySelector('.movie-list').append(temp);
}
});
});
}
해당 코드로 해결은 됐지만..!
fetch를 또 사용하게 되어 효율적인 방법이라고는 느껴지지 않았다
그런데 생각해보니 movieList함수의 내용과 겹치는 부분이 상당히 있어서..!
그 부분을 줄여내면 좀 더 보기 쉬워지지 않을까 싶다