본문 바로가기
JavaScript/Clone Website

[JavaScript] #3.10 Getting the Weather part Two (API) (#코딩공부)

by 함께 공부해요 2020. 4. 7.

https://youtu.be/l6hSze8vgVo


<복습>

https://wook-2124.tistory.com/93

 

[JavaScript] #3.9 Getting the Weather part One (Geolocation) (#코딩공부)

https://youtu.be/5fAMu2ORvDA <복습> https://wook-2124.tistory.com/92 [JavaScript] #3.8 Image Background (#코딩공부) https://youtu.be/aHlJqxLREcY <복습> https://wook-2124.tistory.com/90 [JavaScript]..

wook-2124.tistory.com

 

<준비물>

https://repl.it/

 

Online IDE, Editor, and Compiler - Fast, Powerful, Free

Repl.it is a simple yet powerful online IDE, Editor, Compiler, Interpreter, and REPL. Code, compile, run, and host in 50+ programming languages: Clojure, Haskell, Kotlin (beta), QBasic, Forth, LOLCODE, BrainF, Emoticon, Bloop, Unlambda, JavaScript, CoffeeS

repl.it

 

<코드기록>

// https://openweathermap.org/
// API(Application Programming Interface), 다른 서버로부터 손쉽게 데이터를 가져올 수 있는 수단


// index.html에 span class="js-weather" 추가
<span class="js-weather"></span>


// fetch() - `__` 백틱(backtick)을 이용해서 복사한 URL링크 앞에 https를 적어줌
// lat(latitude 위도), lon(longitude 경도), your api key(API_KEY) 각각 앞에 $ 붙여서 인자화해줌
const API_KEY = "ded8b1690ab3da1a4ef762795e744b2f";

function getWeather(lat, lon) {
  fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}`
  );
}


// else(loadedCoords가 null이 !아니라면)
// parse는 Local Storage에 value로 저장되어있는 string 값을 object 값으로 바꿈
function loadCoords() {
  const loadedCoords = localStorage.getItem(COORDS);
  if (loadedCoords === null) {
    askForCoords();
  } else {
    const parseCoords = JSON.parse(loadedCoords);
    console.log(parseCoords);
  }
}


// getWeather
// F12(inspection)의 network 패널에서 코드가 request한 내용을 보여줌
function loadCoords() {
  const loadedCoords = localStorage.getItem(COORDS);
  if (loadedCoords === null) {
    askForCoords();
  } else {
    const parsedCoords = JSON.parse(loadedCoords);
    getWeather(parsedCoords.latitude, parsedCoords.longitude);
  }
}


// F(fahrenheit, 화씨)에서 C(celsius, 섭씨)로 바꿔서 나타내기
// C를 사용하려면 use 'metric units(미터법)', F를 사용하려면 use 'imperial units(야드 파운드법)'
// "&units=metric"을 URL링크 맨 마지막에 추가해줌
function getWeather(lat, lon) {
  fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
  );
}


// fetch 함수로 서버로부터 전송되는 데이터가 모두 수신될 때까지 기다린 후
// then, 데이터가 수신이 완료된 후 JSON 데이터를 가져옴
function getWeather(lat, lon) {
  fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
  ).then(function(json) {
    console.log(json);
  });
}


// F12(inspection)의 network 패널 안에 있는 response에서 JSON Data만 가져옴
function getWeather(lat, lon) {
  fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
  ).then(function(response) {
    console.log(response.json());
  });
}


// response에서 JSON Data 가져온 것을 보류하지 않고 바로 JSON Data를 출력함
function getWeather(lat, lon) {
  fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
  )
    .then(function(response) {
      return response.json();
    })
    .then(function(json) {
      console.log(json);
    });
}


// 최종 코드
const weather = document.querySelector(".js-weather");

const API_KEY = "ded8b1690ab3da1a4ef762795e744b2f";
const COORDS = "coords";
// temparatur(온도), place(장소)를 각각 JSON Data로 설정하고
// weather.innerText = `__`에 $로 각각 argumentation(인자화)해서 HTML에 출력함 
function getWeather(lat, lon) {
  fetch(
    `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
  )
    .then(function(response) {
      return response.json();
    })
    .then(function(json) {
      const temperature = json.main.temp;
      const place = json.name;
      weather.innerText = `온도: ${temperature} @ 장소: ${place}`;
    });
}

function saveCoords(coordsObj) {
  localStorage.setItem(COORDS, JSON.stringify(coordsObj));
}

function handleGeoSuccess(position) {
  const latitude = position.coords.latitude;
  const longitude = position.coords.longitude;
  const coordsObj = {
    latitude: latitude,
    longitude: longitude
  };
  saveCoords(coordsObj);
  getWeather(latitude, longitude);
}

function handleGeoError(position) {
  console.log("Can't access geo location");
}

function askForCoords() {
  navigator.geolocation.getCurrentPosition(handleGeoSuccess, handleGeoError);
}

function loadCoords() {
  const loadedCoords = localStorage.getItem(COORDS);
  if (loadedCoords === null) {
    askForCoords();
  } else {
    const parsedCoords = JSON.parse(loadedCoords);
    getWeather(parsedCoords.latitude, parsedCoords.longitude);
  }
}

function init() {
  loadCoords();
}

init();

1. API(Application Programming Interface)

API는 다른 서버로부터 손쉽게 data를 가져올 수 있는 수단이다.

 

https://openweathermap.org/

 

Сurrent weather and forecast - OpenWeatherMap

Dashboard and Agro API We provide satellite imagery, weather data and other agricultural services that are based on geodata. By using Agro API , you can easily power your solution based on this information. Dashboard is a visual service where you can easy

openweathermap.org

위 사이트에서 API call 예시들을 볼 수 있다.

 

Examples of API calls을 눌러서 보면 Local Storage에 저장된 data type과 같다. 즉, data type이 string "__" 으로 되어있는데, 이것은 API의 data가 string으로 된 Javascript Object란 것이다.

 

복사해야할 API call을 복사한다음 lat(latitude 위도), lon(longitude 경도), your api key(API_KEY) 각각 앞에 $ 붙여서 argumentation(인자화)해야한다.

 

fetch() 안에 `__` 백틱(backtick)을 이용해서 복사한 URL링크 앞에 https를 적고 $로 argumentation(인자화)했다.

 

하지만 아직 가져온(fetch) weather data가 뜨지 않았는데, 그 이유는 handleGeoSuccess는 Local Storage에 위치정보가 저장되지 않았을 때에만( === null) 실행되기 때문에 else 값을 입력해줘야한다.


2. parse

else의 값은 loadedCoords가 null이 아닐때(!) 실행된다. else의 값으로 JSON.parse를 해줬는데, parse는 Local Storage에 value로 저장되어있는 string값을 object값으로 바꿔준다.

 

parseCoords로 Local Storage에 저장된 string값이 console에 object값으로 출력됐다.

 

parsedCorrds 안에 있는 latitude(위도)와 longitude(경도)만 따로 추출해보자.

 

getWeather이 실행되고, F12(inspection)의 network 패널에서 내가 request한 코드 내용을 보여준다.


3. F(Fahrenheit, 화씨) → C(Celsius, 섭씨)

F12 network 패널의 Request URL 링크로 들어가면 위와 같은 정보들을 확인할 수 있다.

 

coord(좌표)안에 lon(경도), lat(위도) 그리고 weather, temp(F 화씨 기준), clouds, country등을 확인할 수 있다. 

 

Fahrenheit(F, 화씨)는 units=imperial을 사용하면 되고, Celsius(C, 섭씨)는 units=metric을 사용하면 된다고 나와있다.

 

F(화씨)에서 C(섭씨) 기준으로 바꾸고 싶은 것이니, &units=metric를 fetch한 URL 링크 마지막에 추가했다. 

 

반대로 C(섭씨)에서 F(화씨)로 바꾸고 싶으면, &units=imperial을 URL 링크 마지막에 추가해주면 된다.

 

weather.js 본문 말고 Request URL 링크 바로 뒤에 &units=metric를 추가해도 tempature(온도) 정보가 F(화씨)에서 C(섭씨)로 바로 바뀐다.


4. then, JSON(JavaScript Object Notation)

fetch로 API 서버로부터 전송되는 data가 모두 수신될 때까지 기다린 후(then), data가 수신이 완료된 후 JSON data를 가져와보자.

 

JSON data를 console로 확인해보면 body안에 locked: false로 볼 수가 없다.

 

Request URL 링크에 있던 이 정보들이 JSON data이다.

 

아까 F12(inspection)의 network 패널 안에 있는 response에서 JSON 정보를 console로 출력해보자.

 

pending 대기중(보류중)이라고 출력됐다.

 

response에서 JSON Data 가져온 것을 pending(보류)하지 않고, 바로 JSON Data를 console에 출력해보자.

 

Request URL에서 봤던 JSON data가 console에 출력됐다. 여기서 main 안에 있는 temp(온도)와 name(도시이름)을 표출해보자.


5. getWeather

index.html에 <span class="js-weather">를 추가해주고

 

querySelector로 .(class)js-weather를 가져온 뒤, getWeather 함수로 JSON data 중 main에 있는 temparatur(온도), place(장소)를 추출해서 설정하고, querySelector로 설정한 weather에 innerText로 `__`(백틱)에 $로 각각 argumentation(인자화)한 {temperature}와 {place}를 HTML에 출력했다. 

 

API call을 복사한 뒤 API Keys 설정하고, JSON data를 else 값으로 parse해서 LS에 저장된 value인 string값을 object값으로 바꿔준 뒤, 그것을 fetch(가져옴)해서 network 패널에 response가 될 때까지 기다린 후(then) 그 안에서 JSON data만 따로 추출해서 innerText를 이용해서 HTML에 표현했다.

 


※ 코로나19 조심하세요!!!!

댓글