상세 컨텐츠

본문 제목

[TIL] 2024.01.05 영화 API 기반 개인 프로젝트

[TIL]

by 재호링 2024. 1. 5. 23:52

본문

오늘 한 일

개인 프로젝트 인기영화 검색 사이트 제작

API HTML에 표시 

카드 클릭시 영화 id 나타나는 alert 창 구현

검색기능 구현

웹사이트 새로고침 후 검색 input 란에 커서 자동위치 시키기

 

 

프로젝트 설계 

먼저 API를 받아오기 위해 직전 웹종반에서 수강했던

fetch 가져오기를 꼼꼼히 살펴서 설계를 진행했다.

            .then((response) => response.json())
            .then((data) => {
                $('#names-q1').empty()
                let rows = data['RealtimeCityAir']['row']
                rows.forEach((a) => {
                    let gu_name = a['MSRSTE_NM']
                    let gu_mise = a['IDEX_MVL']
                    let temp_html = `<li>${gu_name} : ${gu_mise}</li>`
                    $('#names-q1').append(temp_html)
                });
            })

 

위 코드는 API 응답을 받은 경로를 'gu_name' 변수에 할당하는 과정인데

이 과정을 활용해 아래와 같은 코드를 구현했다.


            .then(response => response.json())
            // .then(response => console.log(response))
            .then((data) => {
                let result = data['results']
                result.forEach(element => {
                    console.log(element)
                    let moviePoster = element['poster_path']
                    let movieTitle = element['title']
                    let movieOverView = element['overview']
                    let movieVoteAvg = element['vote_average']
                    let id = element['id']
                    let temp_html = `
                    <div class="col" onclick="alert('영화 id: ${String(id)}')">
                    <div class="card h-100">
                        ${moviePoster}" alt="">
                        <div class="card-body">
                            <h5 class="card-title">${movieTitle}</h5>
                            <p class="card-text">${movieOverView}</p>
                        </div>
                        <div class="card-footer">
                            <small class="text-body-secondary">Rating: ${movieVoteAvg}</small>
                        </div>
                    </div>
                </div>
                `
                    //document.querySelector(".card").append(temp_html);
                    document.getElementById('card').innerHTML += temp_html
                });

            })
            .catch(err => console.error(err));

 

처음에는 주석처리 되어 있는 querySelector(".card").append(temp_html);을 사용했을땐

콘솔에 오류가 찍혔다. 이유는 DOM요소에 노드를 추가하는데 사용되는 것이고

내가 추가하고 싶은 것은 문자열이기에 당연하게 발생하는 오류 였던것이다.(이거 때문에 시간 많이 날렸다,,)

 

그래서 getElementById를 활용해 문자열을 하나씩 추가되게 코드를 바꿔줬다.

이렇게하면 API를 받아와 영화 카드를 만들어주게된다.

 

문제점

 

이 상태에서 검색기능을 구현하려다 애를 많이 먹었다. 

나는 이때 생각을 filter()를 활용해 대소문자 구분을 없애고 API를 저장해둔 result

를 비교해주면 된다고 생각했다. 근데 result를 then 블록 안에서 선언을 했기 때문에

filter() 함수는 접근 할 수 없는 걸 강의 내용을 통해 알게 되었다.

그래서 변경된 코드를 설명해보자면

 

 let allMovies = [];

            .then(response => response.json())
            .then((data) => {
                allMovies = data['results'];
                displayMovies(allMovies);
            })
            .catch(err => console.error(err));

        function displayMovies(movies) {
            let cardsHTML = '';
            movies.forEach(element => {
                let moviePoster = element['poster_path'];
                let movieTitle = element['title'];
                let movieOverView = element['overview'];
                let movieVoteAvg = element['vote_average'];
                let id = element['id'];

                let temp_html = `
                    <div class="col" onclick="alert('영화 id: ${String(id)}')">
                        <div class="card h-100">
                            ${moviePoster}" alt="">
                            <div class="card-body">
                                <h5 class="card-title">${movieTitle}</h5>
                                <p class="card-text">${movieOverView}</p>
                            </div>
                            <div class="card-footer">
                                <small class="text-body-secondary">Rating: ${movieVoteAvg}</small>
                            </div>
                        </div>
                    </div>
                `;
                cardsHTML += temp_html;
            });

            document.getElementById('card').innerHTML = cardsHTML;
        }

        function searchMovies() {
            const searchInput = document.getElementById('search').value.toLowerCase();
            const filteredMovies = allMovies.filter(element => element.title.toLowerCase().includes(searchInput));
            displayMovies(filteredMovies);
        }

 

먼저 filter()에서 접근할 수 있게 전역 스코프로 allMovies 영화 저장을 하기 위한 배열 선언.

allMovies = data['result'] 는 json으로 되어 있는 'result' 값을 배열안에 저장한다는 의미

 

그리고 displayMovies 함수를 새로 만들어 각 영화 정보를 선언해주고

cardsHTML = '';로 카드를 생성해줌.

temp_html을 담아주는 역할을하기에 위 선언과 함께 담아주지 않으면

innerHTML을 해도 화면에 표시가 되지 않았음.

 

위 과정을 수행하면서 고민을 정말 많이했음.

하드코딩으로 하나씩 직접 꽂아 넣어야되나 싶어서

엎어버리고 처음으로 돌아갔지만 `백틱`을 사용해서 작성해야

코드의 효율성도 늘어나고 하드코딩은 의미가 없다 생각해서

머리를 굴리고 굴리다가 뇌가 절여져버렸다..

모든건 검색 기능을 구현하기 위해 노력한 결과,,

 

searchMovies를 해석해보자면

먼저 searchInput에 search id를 받아와 toLowerCase()를 사용해 소문자로 변환시킨 후

위에서 말했듯이 allMovies는 모든 영화 데이터를 담고 있는 배열이니 

filterdMovies에 filter()함수를 호출해 소문자로 변환시킨 후 includes(searchInput)을 입력하면

영화 정보를 담고 있는 데이터에 내가 입력한 input값을 비교해 결과를 도출해줌.

 

시연 GIF

느낀점

어제 오늘 정말 힘들었다.

될 것 같은데 안되고 시도해보는데 자꾸 오류만 떠서

어떤 오류인지 찾는데만 시간을 허비한 것 같다.

 

다만 이 프로젝트를 하면서 얻은 것은

코드를 하나하나씩 분석해 나가면서 안되는 함수들이여도

왜 적용이 안되는지 이해할 수 있었고, 어느 구역에서 오류가 발생하는지

해결하는 능력을 키워준 프로젝트였다.

 

처음 웹종반 fetch 연습에서 활용한

백틱이 도움이 정말 많이 된 것 같고

getElementBy 메소드를 어떻게 적용해야되는지도

학습 되었다. 함수의 배치 스코프에 대한 이해도도

확실히 실습을 하니 이제 코드 구성은 알아간 느낌.

 

ps..

css를 활용을 제대로 못했다.

카드들을 부트스트랩에서 가져와서

내가 원하는 배열을 만들지 못했다ㅜㅜ

 

그래도 오늘 완성하려고 끝까지 노력한

나에게 칭찬해주고싶다.

 

중간에 시간만 쏟고 오류만 떴을 때

그러다 제대로 된 함수를 사용하고

이해를 했을 때 '아하' 라는 외침과

뿌듯함이 몰려와 포기하지 않은 것 같다.

부디 다음 팀 과제때에도 지치지 않고

큰 일 한 번 내보자!

'[TIL]' 카테고리의 다른 글

[TIL] 2024.01.10  (0) 2024.01.10
[TIL] 2024.01.09  (0) 2024.01.09
[TIL] 2024.01.04  (1) 2024.01.04
[TIL] 2024.01.03  (1) 2024.01.03
[TIL] 2024.01.02 this바인딩  (0) 2024.01.02

관련글 더보기