웹 미니 프로젝트 - 날씨 API 구현 수정

Zyoon·2025년 4월 11일

미니프로젝트

목록 보기
3/35
post-thumbnail

💡온보딩 프로젝트 웹페이지 구현


날씨 정보 구현 수정


  • 기존 코드에서는 현재 날씨가 아닌 다른 시간대의 날씨 정보를 가져오는 오류 발견
  • 현재 시간의 정확한 날씨 정보를 위해 코드 수정
  1. URL 수정

    const url = 
    `https://apis.data.go.kr/1360000/VilageFcstInfoService_2.0/
    getVilageFcst?serviceKey=${serviceKey}
    &pageNo=1&numOfRows=36&dataType=JSON
    &base_date=${base_date}&base_time=${base_time}&nx=${nx}&ny=${ny}`;
    • 날씨정보를 가져오는 url
    • 기존 numOfRows 가 1000으로 설정되어 있었음
    • 필요한 날씨정보는 base_time 기준으로 3시간
    • 1시간 단위마다 12개 type 의 데이터 Row 확인
    • numOfRows 를 36으로 수정
  2. API 에서 제공하는 데이터 양식 확인

    // 각 item 에 들어있는 JSON 양식
    {
    	baseDate: "20250411", //예보를 생성한 날짜
    	baseTime: "1100",     //예보를 생성한 시각
    	category: "TMP",      //예보 항목 코드 (TMP-온도, SKY-상태, PTY-강수)
    	fcstDate: "20250411", //예보 대상 날짜
    	fcstTime: "1200",     //예보 대상 시각
    	fcstValue: "17",      //예보 값 (17도)
    	nx: 60,               //격자 x 좌표
    	ny: 127               //격자 y 좌표
    }
    
    //현재 시간 데이터 가공
    const hour = now.getHours();
    const nowHourBase = String(hour).padStart(2, '0') + '00';
    const base_time = getBaseTime(hour-1);
    • 필요한 정보는 [TMP-온도, SKY-상태, PTY-강수]
    • 지나간 시간은 표시되지 않는다.(예보이기 때문)
    • ex) 현재시간이 11:20 이라면 fcstTime 은 1200부터 표시
    • getBaseTime 에서 -1 을 추가해 현재시간 정보를 가져오도록 설정
  3. Fetch 사용하여 데이터 Get

    //fetch 사용하여 url 요청
    fetch(url)
      .then((response) => {
        if (!response.ok) {
          throw new Error("네트워크 응답에 문제가 있습니다.");
        }
        return response.json();
      })
      .then((data) => {
    	  //리스트 접근
        const items = data.response.body.items.item;
    
        // 예보 시간 기준으로 정렬 (선택 사항)
        const forecast = {};
        //가공된 시간으로 초기화
        forecast[nowHourBase] = {};
    
    		//가공된 시간(현재시간+1)이 일치하는 곳의 온도, 상태 Get
        items.forEach((item) => {
          if (item.fcstTime === nowHourBase) {
            if (item.category === "TMP") {
              forecast[nowHourBase].temp = item.fcstValue;
            } else if (item.category === "SKY") {
              forecast[nowHourBase].sky = item.fcstValue;
            } else if (item.category === "PTY") {
              forecast[nowHourBase].pty = item.fcstValue;
            }
          }
        });
        // 원하는 Data Get
        const currentForecast = forecast[nowHourBase];
        
        //얻은 데이터 형태
        //1100 : {temp: '18', sky: '1', pty: '0'}

PAD 함수


  • pad는 좌우에 특정한 문자열로 채우는 기능
  • 좀더 자세히 얘기하면 첫번째 파라미터인 maxLength를 받아 문자열의 길이가 maxLength보다 작을 경우 나머지를 특정한 문자열로 채워주는 기능
  • 이때 두번째 문자열을 넘겨주지 않으면 빈 공백으로 문자열을 채운다.
    String.prototype.padStart(maxLength, ?fillString);
    String.prototype.padEnd(maxLength, ?fillString);

숫자 앞에 0 붙이기

//달력의 날짜를 표시 할때 01, 02 처럼 숫자 앞에 0을 붙여서 표현한다.
const number = 10;
const size = 4;
const result = String(number).padStrt(size, 0); // 0010

//위의 시간데이터 가공에도 사용
const nowHourBase = String(hour).padStart(2, '0') + '00'; 
//결과 : 0200 -> 10시 이후 : 1000 ~ 2300

아이디를 *로 표시하기

//아이디의 앞부분 일부만 표시를 하고 나머지는 *로 표시 하는 기능
const id = '아이디입니다'
const temp = id.slice(0, 3);
const result = temp.padEnd(id.length, '*'); //아이디***

모듈 타입의 Script 분리


  • 모듈 타입 Import
    //module type script import
    <script type="module" src="main.js"></script>
    • 로컬에서 해당 파일을 열면 모듈 로딩 에러 발생
    • 모듈(type="module")은 보안상 HTTP/HTTPS로만 불러올 수 있음 (CORS 정책 위반)
    • 로컬 서버를 띄우거나, Live Server 사용하여 파일 오픈 가능

Template 태그


  • 브라우저가 초기 렌더링할 때는 무시함 (화면에 안 보임)
  • Template 태그 안에있는 태그들초 초기 렌더링은 안됨 (DOM 트리에는 있음)
  • JS로 꺼내서 붙여주기 전까진 투명한 상태
  • 반복해서 다양한 데이터를 넣어 복수로 활용 가능
  • HTML 코드를 다른 HTML 코드에 Include 할 때도 사용 가능
  1. header.html

    <template id="header-template">
      <header>
        <h1>내 사이트야</h1>
        <nav>
          <a href="/">들어와~</a>
        </nav>
      </header>
    </template>
  2. main.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>템플렛을 넣어야지</title>
    </head>
    <body>
      <div id="header"></div>
    
      <main>
        <p>여긴 본문이야</p>
      </main>
    
      <script src="script.js"></script>
    </body>
    </html>
  3. script.js

    //html 파일 기준 상대경로이기 때문에 module 타입 사용 필요 X
    fetch('header.html')
      .then(res => res.text())
      .then(html => {
        // 문자열 → DOM으로 변환
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = html;
    
        // <template> 꺼내서 클론
        const template = tempDiv.querySelector('#header-template');
        const clone = template.content.cloneNode(true);
    
        // 페이지에 삽입
        document.getElementById('header').appendChild(clone);
      });
  • html 파일을 js 파일 기준으로 경로를 가져올 시에는 type=module 필요
profile
기어 올라가는 개발

0개의 댓글