์์์ ์์์ ์ฌ๋ด์ ์ข ํ์๋ฉด...... 31์ผ ์ดํ์ ์ด์ ์์ผ ๋ง์ง๋ง ํฌ์คํ ์ ํ๊ฒ ๋ ์ด์ . ๊ทธ๋์ ์ทจ์ ์ ์ํด ๋ฉด์ ์ ๋ณด๋ฌ ๋ค๋๊ณ ์ด๋ฐ์ ๋ฐ ์ค๋น๊ฐ ํ์ํด์ ํฌ์คํ ์ ์ฌ์์๋ค. ๊ทธ๋ฌ๋ค ๋ณด๋ ์ด๋๋ง ๋ฒ์จ 6์ ์ค์...! 5์ ๋ด๋ก ๋๋ด๋ ๊ฒ ๋ชฉํ์๋๋ฐ, ๋ฏธ๋ฃจ๊ณ ๋ฏธ๋ฃจ๋ค ์ด๋ ๊ฒ ๋์ด๋ฒ๋ ธ๋ค. ใ ใ ๊ทธ๋๋ ๋ฆ์๋ค๊ณ ์๊ฐํ ๋๊ฐ ๊ฐ์ฅ ๋น ๋ฅธ ๋ฒ! ๋ค์ ๋ฌ๋ ค ๋ณด์!
Weather
Momentum์ ๋ด์ฅ๋์ด ์๋ ๋ ์จ ๊ธฐ๋ฅ์ ๊ตฌํํด ๋ณด๋ ํํธ์ด๋ค. GPS๋ฅผ ์ด์ฉํ์ฌ ์ ์ ๊ฐ ํ์ฌ ์์คํ ์ ์ฌ์ฉํ๊ณ ์๋ ์ง์ญ์ ๋ ์จ๋ฅผ ์์๋ด๊ณ ๋ณด์ฌ ์ค ๊ฒ์ด๋ค.
#1. Geolocation
์ด ํํธ์์ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ๊ฒ์ geolocation์ด๋ค. ์์น๋ผ๋ ์๋ฏธ๋ฅผ ๋ด๊ณ ์๋๋ฐ, getCurrentPosition() ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ์๋์ ๊ฒฝ๋๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. ์ฌ๊ธฐ์ ์ง์คํด์ผ ํ ๊ฒ์? ๋ฐ๋ก ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ๋ฉ์๋์ธ getCurrentPosition().
getCurrentPosition()๋ aargument๊ฐ ๋ ๊ฐ๊ฐ ํ์ํ๋ค. ํ๋๋ ์ฑ๊ณตํ์ ๋ ์คํ๋ ํจ์, ํ๋๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ์คํ๋ ํจ์. ์ฑ๊ณตํ์ ๋ ์คํ๋๋ ํจ์๋ฅผ ์ฑ๊ณต ํจ์, ์๋ฌ๊ฐ ๋ฐ์ํ์ ๋ ์คํ๋ ํจ์๋ฅผ ์๋ฌ ํจ์๋ผ๊ณ ์นญํด ๋ณด์. ์ฑ๊ณต ํจ์๋ ์คํ๋์ ๋ geolocation์ ๊ฐ์ฒด๋ฅผ ๋ฐ๊ฒ ๋๋ค. ์ฆ, ์ ์ ์ ์์น๋ฅผ ์ป๊ฒ ๋๋ ๊ฒ์ด๋ค. ์๋์ ์ฝ๋๋๋ก ์์ฑํ๊ณ ๋ธ๋ผ์ฐ์ ์ ๊ฐ๋ฐ์ ๋๊ตฌ ์ฝ์์ ํ์ธํด ๋ณด์. ์ฝ์์ ์ฐํ ๋ก๊ทธ๋ฅผ ํ์ธํ์ ๋, ๋ด๊ฐ ์์นํ ์๋์ ๊ฒฝ๋๋ฅผ ์ ์ ์๋ค.
function onGeoOk(position) {
console.log(position);
};
function onGeoError() {
alert("Can't find you, No weather for you.")
};
navigator.geolocation.getCurrentPosition(onGeoOk, onGeoError);
geolocation์ด ์๋์ ๊ฒฝ๋๋ฅผ ์ป๋ ๊ฒ์ ํ์ธํ์ผ๋, ์ด์ ์ป์ ๊ฒ์ ์จ๋จน์ด์ผ ํ๋ค. ์ฑ๊ณต ํจ์์ ๋ด๋ถ๋ฅผ ์๋ ์ฝ๋์ ๊ฐ์ด ๋ณ๊ฒฝํ์ฌ ํ ์คํธํด ๋ณด์. ์ฝ์์์ ์๋์ ๊ฒฝ๋๊ฐ ์ ๋ํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
function onGeoOk(position) {
const lat = position.coords.latitude;
const lng = position.coords.longitude;
console.log("You live in", lat, lng);
};
์๋์ ๊ฒฝ๋๋ฅผ ์ป์ด์ค๋ ๊ฒ๊น์ง ๋ง์ณค๋ค๋ฉด, ๋ณธ๊ฒฉ์ ์ผ๋ก geolocation API๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ์, API ๊ณ์ ์ ์ด์ด์ผ ํ๋ค.
https://openweathermap.org/ ์น ์ฌ์ดํธ๋ก ์ด๋ํ์ฌ, ๊ฐ์ ๋๋ ๋ก๊ทธ์ธ์ ํด ์ค๋ค. ๋ก๊ทธ์ธํ ํ์ API๋ผ๋ ๋ฉ๋ด์ ๋ค์ด๊ฐ๋ฉด ์ฌ๋ฌ๊ฐ์ง API๋ฅผ ํ์ธํ ์ ์๋ค.
#2. Weather API
๋จผ์ API๋ผ๋ ๊ฒ์ด ๋ฌด์์ธ์ง ์ง๊ณ ๋์ด๊ฐ์๋ฉด, ๊ฐ๋จํ ๋งํด์ ๋ค๋ฅธ ์๋ฒ์ ์ํตํ๋ ๋ฐฉ๋ฒ์ด๋ผ๊ณ ๋ณผ ์ ์๋ค. ๋ง์ API ์ค์์ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ ๊ฒ์ Current Weather Data์ด๋ค.
API doc์ ์ดํด ๋ณด๋ฉด API ํธ์ถ์ ํ ์ ์๋ ์ฃผ์๊ฐ ํ๋ ์๋ค. ๊ฐ๊ฐ ์๋ง๋ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ฃ์ด ์ฃผ๋ฉด ๋ ์จ์ ์์น ๋ฑ์ ์๋ ค ์ฃผ๋ json์ด ๋ฑ์ฅํ๋ค.
API Key๋ ํ๋กํ์์ My API Key ๋ฉ๋ด์ ๋ค์ด๊ฐ๋ฉด ํ์ธํ ์ ์๋ค.
https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}
// ์ฌ์ฉ ์์๋ {} ์ ๊ฑฐํด ์ฃผ๊ธฐ
๊ทธ๋ ๋ค๋ฉด, ์ด์ ์ด url์ ์ฝ๋์ ์ ๋ชฉํด ๋ณด์. ์ด๋ฏธ ์๋์ ๊ฒฝ๋๋ ์ป๊ณ ์์ผ๋ API Key๋ง ์ค์ ํด ์ค ํ์ url์ ์ค์ ํด ์ฃผ๋ฉด ๋. console.log๊ฐ ์๋ fetch๋ฅผ ์ฌ์ฉํด์ ํ์ธํ๋ค๋ฉด ๊ฐ๋ฐ์ ๋๊ตฌ์ ๋คํธ์ํฌ ํญ์์ URL ์์ฒญ์ ํ๋ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
const API_KEY = "์์ ์ API KEY";
function onGeoOk(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}`;
fetch(url);
};
์ฐ๋ฆฌ๊ฐ ์ค์ง์ ์ผ๋ก ์ป๊ณ ์ถ์๋ ๊ฒ์ ๋ค์ ์๊ฐํด ๋ณด์. ์ ์ ๊ฐ ์๋ ์ง์ญ๊ณผ, ๊ทธ ์ง์ญ์ ๋ ์จ๋ค. ์ง๊ธ ์ฐ๋ฆฌ๊ฐ API๋ฅผ ํตํด ๊ฐ์ ธ์จ json์์ ๋ ๋ชจ๋ ํ์ธํ ์ ์์๋ค. ์ด json์์๋ ์ง์ญ๊ณผ ๋ ์จ ๋ฟ๋ง ์๋๋ผ ์ต๋, ๊ธฐ์จ, ์ผ์ถ, ์ผ๋ชฐ ๋ฑ์ ์ ๋ณด๋ ์ป์ ์๊ฐ ์์๋ค. ๊ทธ๋ฐ๋ฐ, ์ฐ๋ฆฌ๊ฐ ๋ณดํต ์ฌ์ฉํ๋ ์ญ์จ ์จ๋๊ฐ ์๋ ํ์จ ์จ๋๊ฐ ๋ํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋๋ฐ ์ด๊ฒ๋ ์์ ์ด ๊ฐ๋ฅํ๋ค.
API ๋ฌธ์๋ก ๋์๊ฐ ๋ณด๋ฉด, units์ด๋ผ๋ ํ๋ผ๋ฏธํฐ๊ฐ ์๋๋ฐ ์ด๊ฒ์ด ํ์จ์ ์ญ์จ๋ฅผ ์ปจํธ๋กคํ๋ ํ๋ผ๋ฏธํฐ์ด๋ค. ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ url ๋ค์ &units=metric ์ ์ถ๊ฐํด ์ฃผ๋ฉด, ์ญ์จ ์จ๋๋ก ๋ณ๊ฒฝ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ค์ ์ฐ๋ฆฌ๊ฐ ์ฌ์ฉํ fetch๋ก ๋์์์. fetch๋ promise์ด๊ธฐ๋ ํ๋ฐ, promise๋ ๋น์ฅ ์คํ๋์ง ์๊ณ ์๊ฐ์ด ์กฐ๊ธ ์ง๋ ๋ค์ ์คํ๋๋ค. ์๋ฒ์ ์์ฒญํ๋ฉด ์๋ฒ๊ฐ ์๋ตํ๋ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๋ฉด? ๊ทธ ์๊ฐ์ ๊ธฐ๋ค๋ ค์ผ ํ๋ค.
anyway. fetch๊ฐ promise๋ผ๋ฉด? ์์ฒญ์ ๋ฐ์์ผ ํ๋ค. then์ผ๋ก response๋ฅผ ๋ฐ์ ์ฃผ๋ฉด ๋๋ค. ์ฌ๊ธฐ์ response๋ json์ ๋ฐ์ ์ฃผ๊ฒ ๋๊ณ , ์ด json์ด ์ฐ๋ฆฌ๊ฐ ์ฌํ๊น์ง url๋ก ํ์ธํ๋ json์ด๋ค.
json์ ๋ฐ์์๋ค๋ฉด? ์ด์ ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐ์ดํฐ๋ค์ ๊ฐ์ ธ์ ๋ณด์. data.name์ ์ง์ญ์ ์๋ฏธํ๊ณ ์๊ณ , data.weather์ ์ฒซ ๋ฒ์งธ ๋ฐฐ์ด์ main์ ๋ ์จ๋ฅผ ์๋ฏธํ๊ณ ์๋ค. ์ฐ๋ฆฌ๊ฐ ์ํ๋ ๋ฐ์ดํฐ๋ค์ธ ๊ฒ์ด๋ค. ์ด ๋์ ์ฝ์๋ก ์ถ๋ ฅํด ๋ณด๋ฉด, ์ ๋์ค๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
function onGeoOk(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`;
fetch(url).then(response => response.json().then(data => {console.log(`์ง์ญ: ${data.name} / ๋ ์จ: ${data.weather[0].main}`)}));
};
๊ทธ๋ผ ์ด์ ๊ฐ๋ฐ์ ๋๊ตฌ ์ฝ์์ด ์๋ ํ๋ฉด์์ ์ง์ ํ์ธํด ๋ณด์. html ๋ถ๋ถ์์ ์ง์ญ๊ณผ ๋ ์จ๊ฐ ๋ค์ด๊ฐ div์ span์ ์ค์ ํด์ค ํ, js ๋ถ๋ถ์์๋ console.log์ ์ง์ฐ๊ณ ์๋์ ์ฝ๋์ ๊ฐ์ด ์์ฑํ๋ค. ๊ทธ๋ฆฌ๊ณ ์๋ก๊ณ ์นจ์ ํ๋ฉด, ๋ช ์ธ ๋ฐ์ ๋ ์จ๊ฐ ๋ํ๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ์จ๋๋ ํ๋ ๋ฑ๋ ์ถ๊ฐํ ์ ์๋ค. ๋๋ ๋ ธ๋ง๋์ฝ๋์์ ํ๋๋ก ๋ ์จ์ ํจ๊ป ์จ๋๊ฐ ๋ํ๋๋๋ก ์ค์ ํ๋ค.
<div id="weather">
<span></span>
<span></span>
</div>
fetch(url).then(response => response.json().then(data => {
const weatherContainer = document.querySelector("#weather span:first-child");
const city = document.querySelector("#weather span:last-child");
const weather = data.weather[0].main;
const name = data.name;
weatherContainer.innerText = `${weather} / ${data.main.temp}`;
city.innerText = name;
}));
๋ง๋ฌด๋ฆฌ (Conclusions)
์ด์ ์ํ๋ ๊ธฐ๋ฅ์ ๋ชจ๋ ๋ง๋ฌด๋ฆฌ๊ฐ ๋๋ค! ์ด์ ๋จ์ ๊ฑด CSS๋ก ๋ชจ๋ฉํ ์ฒ๋ผ ๊พธ๋ฉฐ๋ด๋ ๊ฒ๋ฟ! ๊ฐ์์์๋ CSS๋ฅผ ๊ตณ์ด ์ค๋ช ํ์ง ์๋๋ค. CSS ์ ๋์ผ, ๊ทธ๋ฆฌ ๋ณต์กํ ํ์ด์ง๊ฐ ์๋๊ธฐ ๋๋ฌธ์ ๋ฌด๋ํ๊ฒ ํผ์ ํ ์ ์์ ๊ฑฐ๋ผ๊ณ ์๊ฐํ์ ๋ฏ? ๋ฌผ๋ก ๋๋ ๊ทธ๋ ๊ฒ ์๊ฐํ๊ณ ์๊ณ . ์๊ณ ์๋ ๊ธฐ์ ๋ค์ ๋ณต์ตํ๊ณ , ๋ค๋ฅธ ๊ธฐ์ ๋ค์ ๋ฐฐ์ธ ์ ์๋ ์ข์ ๊ฐ์์๋ค. ๊ฐ๋ณ๊ฒ ๋ฃ๊ธฐ ๋ฑ ์ข์๋? ๋ฌด๋ฃ ๊ฐ์์ง๋ง ์์ฐผ๋ค. ์ฌ์ค, ๋ด๊ฐ ์ํ๋ ๊ฑด ์ค์ ๋ก ๋ชจ๋ฉํ ์ฒ๋ผ ์ฌ์ฉํ ์ ์๋ ํฌ๋กฌ ์ฑ์ด์์ง๋ง...... ๋ญ ์ด๋! ๊ทธ๊ฑด ๋ ํ๋ฉด ๋๋ ๊ฑฐ๊ณ . ใ ใ
์ด์จ๊ฑฐ๋, ์๋์ CSS๊น์ง ๋ฃ์ด ํธ์คํ ํ ๋ด ๋ชจ๋ฉํ ํด๋ก ํ์ด์ง์ ๋งํฌ๋ฅผ ๋ฌ์ ๋๊ณ ํฌ์คํ ์ ๋ง๋ฌด๋ฆฌํ๊ฒ ๋ค.