내일배움캠프 Spring 3기/웹개발 A to Z

웹개발 A to Z (3) - JQuery, Fetch

yokxim 2024. 8. 10. 09:28

오늘은 이어서 JQuery를 학습하고, 새로운 개념인 Fetch에 대해서 배워보려고 한다.

 

 

오늘 먼저 만들어 보고자 하는 것은 바로 두가지, [영화 기록하기]를 눌렀을 때 기록하기 탭이 나타났다가 없어지는 것과

 

영화 정보를 입력하고 기록하기를 눌렀을 때 새로운 영화 정보가 표시되게 하는 것이다. 

 

 

먼저 <script> 태그를 사용할 건데, 이 태그는 <style>과 <head> 사이에 넣는다.

 
  </style>
  <script>
    function openclose() {
      $('#postingbox').toggle();
    }
  </script>
</head>

이처럼 새로 만들고 싶은 함수 이름을 정하고, function 함수이름() { }을 사용한다.

그리고 JQuery를 사용하려면 언제나 대상을 지정해야 하므로, 여기에서는 '기록하기' 탭을 담았던 <div>에 id 값을 postingbox로 넣어준 뒤, 스크립트 태그 안에서 $('#id값')을 사용해서 명시해주면 된다.

그리고 '영화 기록하기' 버튼을 만들어 주었던 곳에도 버튼을 눌렀을 때 함수가 실행되도록 onclick='함수이름'을 적어주면 된다. 여기에서는 openclose().

그리고 토글 함수를 넣어주면 잘 작동하게 된다!

 

두번째로 영화 정보를 기록하면 새로운 영화 카드가 나타나도록 할 수 있다.

먼저 봐야할 것은 만들어 놓은 postingbox에서 각각 어떤 것들을 가져와야 하느냐이다. 

내가 가져오고 싶은 영화 정보는 4개, 각각 영화 이미지, 영화 제목, 별점, 그리고 추천 이유!

먼저 그 정보를 담은 div class 안에 input 정보에 id 값을 지정해준다. image, title, star, comment

별점은 다른 것들과는 달리 select 구문을 사용하고 있어서, select 태그에 id값을 넣어주면 된다.

 

그리고 함수를 적어보자.

    function makecard() {
      let image = $('#image').val();
      let title = $('#title').val();
      let star = $('#star').val();
      let comment = $('#comment').val();

 

여기에서는 .val() 메서드를 사용해서 유저가 input과 select로 입력한 정보를 가져오도록 했다.

 

그러면 이 정보를 어떻게 홈페이지에 나타나게 할까?

그것은 바로 서버가 클라이언트에게 html 정보를 넘겨주듯이, 나도 html을 적어주면 된다!

먼저 새로운 변수를 만들고, 새로운 카드 정보가 어디 쓰여 있는지 확인해보면.. 

 

이렇게 이미 3개의 영화 카드가 사용된 것을 볼 수 있다.

저 div class = 'col'에 주목해보면, 저 태그가 3번 반복되니 새로운 카드를 집어 넣어주기 위해서는 이 div를 복사해오면 될 것이다.

 
    function makecard() {
      let image = $('#image').val();
      let title = $('#title').val();
      let star = $('#star').val();
      let comment = $('#comment').val();

      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">${star}</p>
                        <p class="card-text">${comment}</p>
                    </div>
                </div>
            </div>`;

그대로 복사해서 함수 안에 넣어준다.

그리고 복사해온 이미지 주소, 영화 제목, 별점, 영화 코멘트를 지워버리고 위에서 image, title, star, comment로 가져온 정보들을 $를 사용해 명시해주면 된다.

마지막으로 이 카드 정보가 어디에 들어가야 할지 보면,

 

3개 카드 정보가 담겼었던 이 mycards div 내부의 row row-cols-1 row -cols-md-4 이 부분이다.

  <div class="mycards">
    <div id="card" class="row row-cols-1 row-cols-md-4 g-4">
      <div class="col">
        <div class="card h-100">

여기에 id 값을 card로 만들어 준 뒤, 만들었던 temp_html 바로 뒤에 

 

            $('#card').append(temp_html);

이 문장을 추가한다.

 

그렇게 되면 기록하기 버튼을 누르면 새로운 카드 정보가 담긴 영화 카드가 생성되는것을 볼 수 있다!

 

 

=========================================

 

이번에는 Fetch에 대해 알아보자! 먼저 Fetch를 사용하기 전에 Fetch에 의해 왔다 갔다 하는 데이터의 형식에 대해 알아보자. 

 

클라이언트들은 언제나 정보를 새로 얻을 때 그 정보를 다른 클라이언트에게서 직접 얻지 않는다. 클라이언트는 서버에 정보를 보내서 저장하거나, 요청해서 가져오는 방식을 사용한다. Fetch는 그 중에 데이터를 요청해서 받아 오는 것을 말하며, 어떤 데이터를 어떻게 가져오는 건지를 살펴보자!

 

서버는 클라이언트에게 일정한 데이터 형식을 유지해서 데이터를 전달해준다.

그것은 바로 JSON 형식!

 

서울시 홈페이지에서 배포하고 있는 각 지역의 미세먼지 수치에 관한 데이터 파일이 있다.

http://openapi.seoul.go.kr:8088/6d4d776b466c656533356a4b4b5872/json/RealtimeCityAir/1/99

 

여기에서 openAPI를 사용했는데, API란 우선 접근하려 하는 데이터에 대한 창구 개념으로 이해하면 된다.

API는 우리에게 접근이 허용된 데이터만 가져갈 수 있게 해 주는데, 여기에서는 openAPI이기 때문에 모두에게 열려 있는 데이터인 것이다.

 

이 정보를 구글 익스텐션인 JsonVue를 사용해서 열어보면, 이런 화면이 나온다.

 

마치 파이썬에서 사용했던 딕셔너리와 유사한 모습이다. key : value 형식이다.

 

Fetch를 연습하기 위해 먼저 새로운 파일을 하나 만들고, 

이 코드를 넣어 연습해보자.

 

<!doctype html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>Fetch 시작하기</title>
    <script>
        function hey() {
            alert('연결완료');
        }
    </script>
</head>

<body>
    <button onclick="hey()">fetch 연습!</button>
</body>

</html>

 

이제 hey() 함수 안에 아까 사용했던 미세먼지 API 주소를 넣어줄건데, url이라는 변수를 만들어서 넣어주자.

 

그리고 fetch 구문을 가져올 건데, 필요할 때마다 긁어서 가져오면 되니까 암기할 필요는 없다!

            fetch(url).then(res => res.json()).then(data => {
                console.log(data)
            })

 

이 구문 안에 아까 만들었던 변수 url을 넣어준다.

그렇다면 버튼을 누르면 console에 어떻게 출력 되는지 확인해보면..

 

이런 식으로 아까 확인했었던 JSON 형식의 데이터가 찍히는 것을 볼 수 있다.

그래서 저렇게 서버에 저장되어 있는 정보를 data라는 이름으로 데이터를 가져올 수 있다는 것이며, 우리는 여기에 인덱스 값을 추가해서 특정 정보만 추출해서 가져올 수도 있다.

                console.log(data['RealtimeCityAir']['row'][0])

이렇게 딕셔너리를 쓰는 것처럼 RealtimeCityAir의 첫번째 row 값만을 가져온 모습이다.

 

이번에는 반복문을 사용해서 데이터를 가져와보자!

       function hey() {
            fetch(url).then(res => res.json()).then(data => {
                let rows = data['RealtimeCityAir']['row'];
                rows.forEach(a => {
                    console.log(a);
                });
            })
        }

반복문을 적용할 구역을 먼저 변수로 지정해주고, forEach를 사용했다.

 

그러면 row에 해당하는 데이터를 여러번 반복해서 가져온 모습을 확인할 수 있다.

그렇다면 이 가져온 데이터를 어떻게 이용할 수 있을까?

연습을 위해 새로운 파일을 하나 더 만들고 아래 코드를 넣어주자.

 

<!doctype html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <title>미세먼지 API로Fetch 연습하고 가기!</title>


    <style type="text/css">
        div.question-box {
            margin: 10px 0 20px 0;
        }
    </style>

    <script>
        function q1() {
            // 여기에 코드를 입력하세요
        }
    </script>

</head>

<body>
    <h1>Fetch 연습하자!</h1>

    <hr/>

    <div class="question-box">
        <h2>1. 서울시 OpenAPI(실시간 미세먼지 상태)를 이용하기</h2>
        <p>모든 구의 미세먼지를 표기해주세요</p>
        <p>업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.</p>
        <button onclick="q1()">업데이트</button>
        <ul id="names-q1">
            <li>중구 : 82</li>
            <li>종로구 : 87</li>
            <li>용산구 : 84</li>
            <li>은평구 : 82</li>
        </ul>
    </div>
</body>

</html>

 

먼저 아까 연습했던 function hey()를 그대로 가져와서 새로운 파일 script 태그에 넣는다.

function q1() {
            fetch(url).then(res => res.json()).then(data => {
                let rows = data['RealtimeCityAir']['row'];
                rows.forEach(a => {
                    let gu_name = a['MSRSTE_NM'];
                    let gu_mise = a['IDEX_MVL'];
                    console.log(gu_name, gu_mise);
                });
            })
        }

그리고 지역 정보를 담은 MSRSTE_NM 과 IDEX_MVL key name을 사용해서 지역정보:미세먼지 정보를 담는 출력창을 띄워봤다.

 

그러면 업데이트를 누르면 이런 데이터가 표시된다.

이제 홈페이지 위에 이 정보가 뜨게 하려면, 아까 JQuery할 때 연습했던 것처럼 html을 만들어줘야 한다.

 

먼저 사용할 html의 구조를 살펴보면,

    <div class="question-box">
        <h2>1. 서울시 OpenAPI(실시간 미세먼지 상태)를 이용하기</h2>
        <p>모든 구의 미세먼지를 표기해주세요</p>
        <p>업데이트 버튼을 누를 때마다 지웠다 새로 씌여져야 합니다.</p>
        <button onclick="q1()">업데이트</button>
        <ul id="names-q1">
            <li>중구 : 82</li>
            <li>종로구 : 87</li>
            <li>용산구 : 84</li>
            <li>은평구 : 82</li>
        </ul>
    </div>

 

<li>중구:82</li>가 내가 원하는 그 구조다. 이 구조 위에 names-q1이라는 이름도 있으니 사용해보자.

 

function q1() {
            fetch(url).then(res => res.json()).then(data => {
                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);
                });
            })
        }

 

이렇게 데이터 정보를 입력해주고, append를 사용해서 temp_html의 정보를 넣어주면?

 

 

이렇게 내가 원하는 모습으로 데이터가 찍히는 것을 볼 수 있다.

하지만 이렇게만 하면 업데이트를 누를 때마다 이 많은 텍스트가 추가되므로.. empty()를 사용해서 업데이트를 누를 때마다 기존 데이터를 지워주면 된다.

fetch(url).then(res => res.json()).then(data => {
                let rows = data['RealtimeCityAir']['row'];
                $('#names-q1').empty();
                rows.forEach(a => {

 

만약에 여기서 하나를 더 추가해서 미세먼지 농도가 40보다 높은 곳의 텍스트를 빨갛게 표시해주고 싶다면, if구문을 집어 넣어주면 된다.

 

 rows.forEach(a => {
                    let gu_name = a['MSRSTE_NM'];
                    let gu_mise = a['IDEX_MVL'];
                   
                    let temp_html = ``;
                    if (gu_mise > 40)
                    {
                        temp_html = `<li>${gu_name} : <span class='bad'>${gu_mise}</span></li>`;
                    }
                    else
                    {
                        temp_html = `<li>${gu_name} : ${gu_mise}</li>`;
                    }
                    $('#names-q1').append(temp_html);
                });

 

gu_mise를 담는 span 태그를 만들어 주고, 그 태그의 아이디를 만들어 준다.

그리고 스타일 태그로 가서 그 아이디에 color: red를 추가해주기만 하면 된다!

 

그렇게 하면 40수치가 넘을 때는 bad로 gu_mise 정보가 빨간색으로 칠해지게 될 것이고, 그렇지 않다면 원래 일반 텍스트로 보이게 될 것이다.

 

 

3주차는 여기까지!

4주차 때에는 파이어베이스와 파이어스토어에 대해 배워보자.