wisePocket

[JavaScript] Fetch, 공공 데이터 OpenAPI 활용 실습 - 4 본문

Python&Flask Tutorials, AWS EB/2nd WEEK JavaScript, JQuery, Fetch, API

[JavaScript] Fetch, 공공 데이터 OpenAPI 활용 실습 - 4

ohnyong 2023. 7. 3. 17:53

본문 card 부분도 하드코딩이 아니라 제공된 소스를 API를 받은 것 처럼 받아와서

card 형태로 붙이는것을 해보자.

리뷰들이 담긴 API를 받아오기부터 시작.

1. 기존 작업한 웹 페이지에 fetch에 OpenAPI 링크 설정

 

기초 HTML 뼈대는 다음과 같다.

 

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />

    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
        integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
        integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
        crossorigin="anonymous"></script>

    <title>스파르타 피디아</title>
    <!-- style.css 파일을 같은 폴더에 만들고, head 태그에서 불러오기 -->
    <link rel="stylesheet" type="text/css" href="style.css">
    <link href="https://fonts.googleapis.com/css2?family=Gowun+Dodum&display=swap" rel="stylesheet" />

    <style>
        /* style.css로 모듈화 시킴 */
        .red {
            color: red;
        }

        .blue {
            color: blue;
        }
    </style>

    <script>
        $(document).ready(function () {
            fetch("http://spartacodingclub.shop/sparta_api/weather/seoul").then(res => res.json()).then(data => {
                console.log(data)


                let temp = data['temp']
                // 데이터 들어오는지 확인
                console.log(temp)
                $('#temp').empty()
                // if (temp > 20){
                //     $('#temp').append("<span class='red'>"+temp+"</span>")
                // } else{
                //     $('#temp').append("<span class='blue'>"+temp+"</span>")
                // }
                // 즉석으로 생각 흐름따라 단순하게 코딩하니 뭔가 효율이 엄청 떨어지는 코드다.

                // 이 부분은 원래 class가 있는 span을 추가하는 것 말고
                // 기존의 temp span에 클래스 속성을 red or blue로 변경되는 것을 생각..
                // 속성을 바꾸려면 .attr(‘속성’,’값’)을 써야한다.
                // 또한 과제 해설에서는 
                // $('#temp').text(temp)
                // 로 진행되었다. 

                // 검색을 통해서 확인한것
                // 속성을 바꾸는 경우 .attr(‘속성’,’값’)을 쓸수 있다.
                // 선택한 요소의 속성을 생성,수정 하는 동작
                // 한번 사용해보자
                $('#temp').text(temp)
                if (temp > 20) {
                    $('#temp').attr('class', 'red')
                } else {
                    $('#temp').attr('class', 'blue')
                }
            })
        })
    </script>

</head>

<body>
    <div class="mytitle">
        <h1>내 생애 최고의 영화들</h1>
        <div>현재 서울의 날씨 : <span id="temp">20</span>도</div>
        <button onclick="hey()">영화 기록하기</button>
    </div>
    <div class="mypost">
        <div class="form-floating mb-3">
            <input type="email" class="form-control" id="floatingInput" placeholder="name@example.com" />
            <label for="floatingInput">URL</label>
        </div>


        <!-- 별점 갯수 https://getbootstrap.com/docs/5.0/forms/input-group/ -->
        <div class="input-group mb-3">
            <label class="input-group-text" for="inputGroupSelect01">Review Score</label>
            <select class="form-select" id="inputGroupSelect01">
                <option selected>Select Your Score</option>
                <option value="1">⭐</option>
                <option value="2">⭐⭐</option>
                <option value="3">⭐⭐⭐</option>
                <option value="4">⭐⭐⭐⭐</option>
                <option value="5">⭐⭐⭐⭐⭐</option>
            </select>
        </div>


        <div class="form-floating">
            <textarea class="form-control" placeholder="Leave a comment here" id="floatingTextarea2"
                style="height: 100px"></textarea>
            <label for="floatingTextarea2">Comment</label>
        </div>
        <div class="mybtns">
            <button type="button" class="btn btn-dark">Write</button>
            <button type="button" class="btn btn-outline-dark">Close</button>
        </div>
    </div>
    <div class="mycards">
        <div class="row row-cols-1 row-cols-md-4 g-4">
            <div class="col">
                <div class="card h-100">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="..." />
                    <div class="card-body">
                        <h5 class="card-title">영화 제목이 들어갑니다</h5>
                        <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                        <p>⭐⭐⭐</p>
                        <p class="mycomment">나의 한줄 평을 씁니다</p>
                    </div>
                </div>
            </div>

            <div class="col">
                <div class="card h-100">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="..." />
                    <div class="card-body">
                        <h5 class="card-title">영화 제목이 들어갑니다</h5>
                        <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                        <p>⭐⭐⭐</p>
                        <p class="mycomment">나의 한줄 평을 씁니다</p>
                    </div>
                </div>
            </div>

            <div class="col">
                <div class="card h-100">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="..." />
                    <div class="card-body">
                        <h5 class="card-title">영화 제목이 들어갑니다</h5>
                        <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                        <p>⭐⭐⭐</p>
                        <p class="mycomment">나의 한줄 평을 씁니다</p>
                    </div>
                </div>
            </div>

            <div class="col">
                <div class="card h-100">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="..." />
                    <div class="card-body">
                        <h5 class="card-title">영화 제목이 들어갑니다</h5>
                        <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                        <p>⭐⭐⭐</p>
                        <p class="mycomment">나의 한줄 평을 씁니다</p>
                    </div>
                </div>
            </div>
            <!-- col -->
        </div>
        <!-- card -->
    </div>
</body>

</html>

 

하단에 나열되는 "영화포스터+제목+설명+별점+한줄평" 부분이 하드코딩이 아닌

지정한 데이터로부터 추출되어 나열되게 하는 것이 목표이다.

 

하드코딩된 부분만 분리하면 다음과 같다.

추후 데이터를 입력 하는 반복문에서 아래처럼 섹션을 구분하기 위한 class 명칭들을 이용하게 될 것 같다.

"영화포스터+제목+설명+별점+한줄평" 부분

            <div class="col">
                <div class="card h-100">
                    <img src="https://movie-phinf.pstatic.net/20210728_221/1627440327667GyoYj_JPEG/movie_image.jpg"
                        class="card-img-top" alt="..." />
                    <div class="card-body">
                        <h5 class="card-title">영화 제목이 들어갑니다</h5>
                        <p class="card-text">여기에 영화에 대한 설명이 들어갑니다.</p>
                        <p>⭐⭐⭐</p>
                        <p class="mycomment">나의 한줄 평을 씁니다</p>
                    </div>
                </div>
            </div>

 

 

 

2. Fetch 기본 골격 코드와 OpenAPI 코드를 통해 데이터를 받아오자.

Fetch 기본 골격을 추가했다.

        // 본문 card 부분도 하드코딩이 아니라 API를 통해 card 형태로 붙이는것을 해보자.
        // 리뷰들이 담긴 API를 받아오기부터 시작.
        fetch("http://spartacodingclub.shop/web/api/movie").then(res => res.json()).then(data => {
            console.log(data)
        })

 

OpenAPI URL : 

URL 부분 "http://spartacodingclub.shop/web/api/movie" 로 변경

 

OpenAPI의 데이터가 들어오는지부터 확인한다.

console.log를 통해 정상적으로 데이터가 들어오는지 확인한다.

 

또한 "영화포스터+제목+설명+별점+한줄평" 부분이 어떤 key값을 쓰고 있는지 확인 할 수 있다.

이전과 직전 실습과 같이

데이터 Dictionary 구조는

하위구조 없이 movies라는 리스트로 직접 데이터를 추출 할 수 있다.

 

rows라는 변수에 데이터를 담는다

            let rows = data['movies']

rows를 반복문으로 데이터를 확인한다.

            rows.forEach((a) => {
                console.log(a)
            });

**여기서 이전 과정에서 for 루프는 자주 사용했지만

            for (i = 0; i < rows.length; i++) {
                console.log(rows[i]);
            }

이번 실습 과정에서는 forEach 반복문을 자주 사용하더라..

            rows.forEach((a) => {
                console.log(a)
            });

동일한 결과가 나오지만

정확한 차이점, 쓰는 이유 등을 모르겠다.

forEach가 경제적이라면 익숙해질 필요가 있다.

이것에 대해서는 다시 금방 개념을 정리해서 공부해야겠다.

 

다시 실습으로 돌아와서 forEach 반복문에서

변수들에 데이터 값들을 넣는다.

  • title = 제목
  • desc = 설명
  • comment = 한줄평
  • star = 별점
  • image = 영화포스터

에 각 값들을 넣어준다.

        // 본문 card 부분도 하드코딩이 아니라 API를 통해 card 형태로 붙이는것을 해보자.
        // 리뷰들이 담긴 API를 받아오기부터 시작.
        
        fetch("http://spartacodingclub.shop/web/api/movie").then(res => res.json()).then(data => {

            let rows = data['movies']

            //--------이 과정에서 주로 사용하는 반복문--------
            rows.forEach((a) => {
                // key값들을 변수에 각각 선언해서 담아보자
                let title = a['title']
                let desc = a['desc']
                let comment = a['comment']
                let star = a['star']
                let image = a['image']
                console.log(title,desc,comment,star,image)
            });
        })

title, desc, comment, star, image 로 원하는 값들이 나열되고 반복문으로 했기 때문에 한줄마다 구분되었다.

이제 준비가 되었으니 HTML에 원하는 필드에 value들을 넣어주기만 하면 된다.

 

 

3. 데이터가 들어오는 것을 확인했으면 HTML에 기록되도록 해보자

append 를 통해 HTML에 붙이는 것을 하면 된다.

어떤 부분이 교체되어야 하는지는 코드 접기 기능으로 시각적으로 확인하는 것이 실수를 줄일 수 있다.

div중 cards란 id를 가진 부분에

하위 col클래스를 가진 div 묶음이 추가되어야 한다.

 

            //--------이 과정에서 주로 사용하는 반복문--------
            $('#cards').empty()
            rows.forEach((a) => {
                // console.log(a)

                // key값들을 변수에 각각 선언해서 담아보자
                let title = a['title']
                let desc = a['desc']
                let comment = a['comment']
                let star = a['star']
                let image = a['image']
                console.log(title, desc, comment, star, image)

                let temp_html = `<div class="col">
                                    <div class="card h-100">
                                        <img src="${image}"
                                            class="card-img-top" alt="..." />
                                        <div class="card-body">
                                            <h5 class="card-title">${title}</h5>
                                            <p class="card-text">${desc}</p>
                                            <p>⭐⭐⭐</p>
                                            <p class="mycomment">${comment}</p>
                                        </div>
                                    </div>
                                </div>`

                $('#cards').append(temp_html)
            });
        })

temp_html이라는 변수에 각 데이터들을 ${ ??? }로 넣어주고

해당 div 블록을

id가 cards라는 div태그에 반복하면서 append로 넣어준다.

이전 하드코딩된 부분은 맨 위에서 반복문 이전에 empty()로 비워준다.

이 과정을 지나가면 다음과 같이 나타난다

 

추가적으로 별점에 대한 부분이 추가작업이 필요하다.

star라는 변수에 저장된 값이 1,2,3,4,5로 나타나고

값마다 별을 추가하는 방식으로 접근

위 코드의 반복문 내부에 star_image라는 변수를 선언하고 .repeat()함수로 star숫자 만큼 반복되서 찍히게 한다.

반복문 cards의 별점 부분을 바로 위 ${star_image}가 들어가도록 한다.

                // 별 추가 부분
                let star_image = '⭐'.repeat(star)
<p>${star_image}</p>

이제 데이터의 star 의 값에 따라 별 이미지의 점수가 다르게 표현되는 것을 볼 수 있다.

 

 


 

해당 스터디는 아래 깃을 통해 업데이트 되고 있습니다.

https://github.com/yzpocket/Sparta99training

 

GitHub - yzpocket/Sparta99training

Contribute to yzpocket/Sparta99training development by creating an account on GitHub.

github.com