Showing
5 changed files
with
202 additions
and
16 deletions
... | @@ -16,6 +16,7 @@ function App() { | ... | @@ -16,6 +16,7 @@ function App() { |
16 | setWeather(null); | 16 | setWeather(null); |
17 | setForecast(null); | 17 | setForecast(null); |
18 | setAir(null); | 18 | setAir(null); |
19 | + // TODO: settimeout for data fetch from openweather api? | ||
19 | if (e.target.id === "weather") { | 20 | if (e.target.id === "weather") { |
20 | const weatherData = await weatherService.getWeather(token); | 21 | const weatherData = await weatherService.getWeather(token); |
21 | setWeather(weatherData); | 22 | setWeather(weatherData); |
... | @@ -35,8 +36,8 @@ function App() { | ... | @@ -35,8 +36,8 @@ function App() { |
35 | return ( | 36 | return ( |
36 | <div> | 37 | <div> |
37 | <Topbar /> | 38 | <Topbar /> |
38 | - <h1>Weather Page (home)</h1> | ||
39 | <div className="weather-buttons"> | 39 | <div className="weather-buttons"> |
40 | + <b>Types : </b> | ||
40 | <button id="weather" onClick={(e) => handleData(e)}> | 41 | <button id="weather" onClick={(e) => handleData(e)}> |
41 | Weather | 42 | Weather |
42 | </button> | 43 | </button> |
... | @@ -53,11 +54,12 @@ function App() { | ... | @@ -53,11 +54,12 @@ function App() { |
53 | ) : ( | 54 | ) : ( |
54 | <div> | 55 | <div> |
55 | <h2> | 56 | <h2> |
56 | - {weather.meta.city} ({weather.meta.country}) - {weather.description} | 57 | + {weather.meta.city} ({weather.meta.country}){" "} |
58 | + <small>UTC {weather.meta.timezone}</small> | ||
57 | </h2> | 59 | </h2> |
58 | - <small>Time Zone : UTC {weather.meta.timezone}</small> | 60 | + <h3>* {weather.description} *</h3> |
59 | <p> | 61 | <p> |
60 | - Temperature : {weather.temp.realCelcius} C / feels like{" "} | 62 | + Temperature : {weather.temp.realCelcius} ℃ / feels like{" "} |
61 | {weather.temp.feelCelcius} C | 63 | {weather.temp.feelCelcius} C |
62 | </p> | 64 | </p> |
63 | <p>Wind : {weather.types.wind} m/s</p> | 65 | <p>Wind : {weather.types.wind} m/s</p> |
... | @@ -67,6 +69,51 @@ function App() { | ... | @@ -67,6 +69,51 @@ function App() { |
67 | </div> | 69 | </div> |
68 | )} | 70 | )} |
69 | 71 | ||
72 | + {!forecast ? ( | ||
73 | + "" | ||
74 | + ) : ( | ||
75 | + <div> | ||
76 | + <h2> | ||
77 | + {forecast.meta.city} ({forecast.meta.country}){" "} | ||
78 | + <small>UTC {forecast.meta.timezone}</small> | ||
79 | + </h2> | ||
80 | + | ||
81 | + {forecast.forecast.map((item, index) => ( | ||
82 | + <div key={index} className="forecastItemBox"> | ||
83 | + <h3> | ||
84 | + {item.description} <small>{item.dateTime}</small> | ||
85 | + </h3> | ||
86 | + <p> | ||
87 | + Temperature : {item.temp.realCelcius} ℃ / feels like{" "} | ||
88 | + {item.temp.feelCelcius} ℃ | ||
89 | + </p> | ||
90 | + <p>Wind : {item.types.wind} m/s</p> | ||
91 | + <p>Cloud : {item.types.clouds} %</p> | ||
92 | + </div> | ||
93 | + ))} | ||
94 | + </div> | ||
95 | + )} | ||
96 | + | ||
97 | + {!air ? ( | ||
98 | + "" | ||
99 | + ) : ( | ||
100 | + <div> | ||
101 | + <h2> | ||
102 | + {air.meta.country} {air.meta.state ? air.meta.state : ""} | ||
103 | + </h2> | ||
104 | + <p>CO : {air.airData.co} μg/m3</p> | ||
105 | + <p>NH3 : {air.airData.nh3} μg/m3</p> | ||
106 | + <p>NO : {air.airData.no} μg/m3</p> | ||
107 | + <p>NO2 : {air.airData.no2} μg/m3</p> | ||
108 | + <p>O3 : {air.airData.o3} μg/m3</p> | ||
109 | + <p>SO2 : {air.airData.so2} μg/m3</p> | ||
110 | + <p> | ||
111 | + {"pm2.5"} : {air.airData.pm2_5} μg/m3 | ||
112 | + </p> | ||
113 | + <p>pm10 : {air.airData.pm10} μg/m3</p> | ||
114 | + </div> | ||
115 | + )} | ||
116 | + | ||
70 | <Bottombar /> | 117 | <Bottombar /> |
71 | </div> | 118 | </div> |
72 | ); | 119 | ); | ... | ... |
... | @@ -35,12 +35,83 @@ const getWeather = async (user) => { | ... | @@ -35,12 +35,83 @@ const getWeather = async (user) => { |
35 | } | 35 | } |
36 | }; | 36 | }; |
37 | 37 | ||
38 | -const getForecaset = async () => { | 38 | +const getForecaset = async (user) => { |
39 | + if (!user) { | ||
39 | return; | 40 | return; |
41 | + } | ||
42 | + try { | ||
43 | + const response = await axios.post( | ||
44 | + "http://localhost:8080/api/weather/forecast" | ||
45 | + ); | ||
46 | + const data = response.data; | ||
47 | + | ||
48 | + const forecast = []; | ||
49 | + for (let i = 0; i < data.list.length; i++) { | ||
50 | + const singleData = {}; | ||
51 | + let singleItem = data.list[i]; | ||
52 | + singleData["dateTime"] = singleItem.dt_txt; | ||
53 | + singleData["description"] = singleItem.weather[0].description; | ||
54 | + singleData["temp"] = { | ||
55 | + realCelcius: (singleItem.main.temp - 273.15).toFixed(2), | ||
56 | + feelCelcius: (singleItem.main.feels_like - 273.15).toFixed(2), | ||
57 | + realFer: ((singleItem.main.temp - 273.15) * 9) / 5 + 32, | ||
58 | + feelFer: ((singleItem.main.feels_like - 273.15) * 9) / 5 + 32, | ||
59 | + }; | ||
60 | + singleData["types"] = { | ||
61 | + wind: singleItem.wind.speed, | ||
62 | + clouds: singleItem.clouds.all, | ||
63 | + }; | ||
64 | + forecast.push(singleData); | ||
65 | + } | ||
66 | + | ||
67 | + const formattedData = { | ||
68 | + meta: { | ||
69 | + country: data.city.country, | ||
70 | + city: data.city.name, | ||
71 | + timezone: data.city.timezone / 60 / 60, | ||
72 | + sunrise: data.city.sunrise, | ||
73 | + sunset: data.city.sunset, | ||
74 | + }, | ||
75 | + forecast, | ||
76 | + }; | ||
77 | + return formattedData; | ||
78 | + } catch (err) { | ||
79 | + console.log(err); | ||
80 | + } | ||
40 | }; | 81 | }; |
41 | 82 | ||
42 | -const getAirPollution = async () => { | 83 | +const getAirPollution = async (user) => { |
84 | + if (!user) { | ||
43 | return; | 85 | return; |
86 | + } | ||
87 | + try { | ||
88 | + const response = await axios.post( | ||
89 | + "http://localhost:8080/api/weather/airpollution" | ||
90 | + ); | ||
91 | + const dataObject = response.data; | ||
92 | + const airData = dataObject.airPollutionData.list[0].components; | ||
93 | + | ||
94 | + const formattedData = { | ||
95 | + meta: { | ||
96 | + country: dataObject.country, | ||
97 | + state: dataObject.state ? dataObject.state : null, | ||
98 | + coordinates: dataObject.airPollutionData.coord, | ||
99 | + }, | ||
100 | + airData: { | ||
101 | + co: airData.co, | ||
102 | + nh3: airData.nh3, | ||
103 | + no: airData.no, | ||
104 | + no2: airData.no2, | ||
105 | + o3: airData.o3, | ||
106 | + pm2_5: airData.pm2_5, | ||
107 | + pm10: airData.pm10, | ||
108 | + so2: airData.so2, | ||
109 | + }, | ||
110 | + }; | ||
111 | + return formattedData; | ||
112 | + } catch (err) { | ||
113 | + console.log(err); | ||
114 | + } | ||
44 | }; | 115 | }; |
45 | 116 | ||
46 | const weatherService = { | 117 | const weatherService = { | ... | ... |
... | @@ -32,3 +32,17 @@ | ... | @@ -32,3 +32,17 @@ |
32 | margin-right: 0.2rem; | 32 | margin-right: 0.2rem; |
33 | } | 33 | } |
34 | } | 34 | } |
35 | + | ||
36 | +.forecastItemBox { | ||
37 | + margin-bottom: 0.3rem; | ||
38 | + padding: 0.1rem; | ||
39 | + border: 2px gray solid; | ||
40 | + border-radius: 4px; | ||
41 | + | ||
42 | + p { | ||
43 | + font-size: 0.9rem; | ||
44 | + } | ||
45 | + small { | ||
46 | + font-size: 0.7rem; | ||
47 | + } | ||
48 | +} | ... | ... |
... | @@ -9,11 +9,12 @@ const asyncHandler = require("express-async-handler"); | ... | @@ -9,11 +9,12 @@ const asyncHandler = require("express-async-handler"); |
9 | // @access Public | 9 | // @access Public |
10 | const getWeather = asyncHandler(async (req, res) => { | 10 | const getWeather = asyncHandler(async (req, res) => { |
11 | const countryCode = "US"; | 11 | const countryCode = "US"; |
12 | - const cityName = "los angeles"; | 12 | + const city = "los angeles"; |
13 | const limit = 5; | 13 | const limit = 5; |
14 | 14 | ||
15 | + try { | ||
15 | const metaGeoData = await axios.get( | 16 | const metaGeoData = await axios.get( |
16 | - `http://api.openweathermap.org/geo/1.0/direct?q=${cityName},${countryCode}&limit=${limit}&appid=${process.env.OPENWEATHER_API_KEY}` | 17 | + `http://api.openweathermap.org/geo/1.0/direct?q=${city},${countryCode}&limit=${limit}&appid=${process.env.OPENWEATHER_API_KEY}` |
17 | ); | 18 | ); |
18 | const data = metaGeoData.data[0]; | 19 | const data = metaGeoData.data[0]; |
19 | const geoData = { | 20 | const geoData = { |
... | @@ -29,25 +30,78 @@ const getWeather = asyncHandler(async (req, res) => { | ... | @@ -29,25 +30,78 @@ const getWeather = asyncHandler(async (req, res) => { |
29 | const weatherData = metaData.data; | 30 | const weatherData = metaData.data; |
30 | 31 | ||
31 | res.json(weatherData); | 32 | res.json(weatherData); |
33 | + } catch (err) { | ||
34 | + res.status(400); | ||
35 | + throw new Error("openweathermap API error"); | ||
36 | + } | ||
32 | }); | 37 | }); |
33 | 38 | ||
34 | // @desc Get weather forecast (3-hour Forecast 5 days) | 39 | // @desc Get weather forecast (3-hour Forecast 5 days) |
35 | // @route GET /api/weather/forecast | 40 | // @route GET /api/weather/forecast |
36 | // @access Public | 41 | // @access Public |
37 | const getForecast = asyncHandler(async (req, res) => { | 42 | const getForecast = asyncHandler(async (req, res) => { |
38 | - const lat = 35; | 43 | + const countryCode = "KR"; |
39 | - const lon = 139; | 44 | + const city = "seoul"; |
40 | - const data = await axios.get( | 45 | + const limit = 5; |
41 | - `https://pro.openweathermap.org/data/2.5/forecast/hourly?lat=${lat}&lon=${lon}&appid=${process.env.OPENWEATHER_API_KEY2}` | 46 | + |
47 | + try { | ||
48 | + const metaGeoData = await axios.get( | ||
49 | + `http://api.openweathermap.org/geo/1.0/direct?q=${city},${countryCode}&limit=${limit}&appid=${process.env.OPENWEATHER_API_KEY}` | ||
42 | ); | 50 | ); |
43 | - console.log(data); | 51 | + const data = metaGeoData.data[0]; |
52 | + const geoData = { | ||
53 | + lat: data.lat, | ||
54 | + lon: data.lon, | ||
55 | + country: data.country, | ||
56 | + state: data.state, | ||
57 | + }; | ||
58 | + | ||
59 | + const metaData = await axios.get( | ||
60 | + `http://api.openweathermap.org/data/2.5/forecast?lat=${geoData.lat}&lon=${geoData.lon}&appid=${process.env.OPENWEATHER_API_KEY}` | ||
61 | + ); | ||
62 | + const forecastData = metaData.data; | ||
63 | + | ||
64 | + res.json(forecastData); | ||
65 | + } catch (err) { | ||
66 | + res.status(400); | ||
67 | + throw new Error("openweathermap API error"); | ||
68 | + } | ||
44 | }); | 69 | }); |
45 | 70 | ||
46 | // @desc Get air pollution (Air Pollution API) | 71 | // @desc Get air pollution (Air Pollution API) |
47 | // @route GET /api/weather/airpollution | 72 | // @route GET /api/weather/airpollution |
48 | // @access Public | 73 | // @access Public |
49 | const getAirPollution = asyncHandler(async (req, res) => { | 74 | const getAirPollution = asyncHandler(async (req, res) => { |
50 | - res.json({}); | 75 | + const countryCode = "US"; |
76 | + const city = "san francisco"; | ||
77 | + const limit = 5; | ||
78 | + | ||
79 | + try { | ||
80 | + const metaGeoData = await axios.get( | ||
81 | + `http://api.openweathermap.org/geo/1.0/direct?q=${city},${countryCode}&limit=${limit}&appid=${process.env.OPENWEATHER_API_KEY}` | ||
82 | + ); | ||
83 | + const data = metaGeoData.data[0]; | ||
84 | + const geoData = { | ||
85 | + lat: data.lat, | ||
86 | + lon: data.lon, | ||
87 | + country: data.country, | ||
88 | + state: data.state, | ||
89 | + }; | ||
90 | + | ||
91 | + const metaData = await axios.get( | ||
92 | + `http://api.openweathermap.org/data/2.5/air_pollution?lat=${geoData.lat}&lon=${geoData.lon}&appid=${process.env.OPENWEATHER_API_KEY}` | ||
93 | + ); | ||
94 | + const airPollutionData = metaData.data; | ||
95 | + | ||
96 | + res.json({ | ||
97 | + country: geoData.country, | ||
98 | + state: geoData.state, | ||
99 | + airPollutionData, | ||
100 | + }); | ||
101 | + } catch (err) { | ||
102 | + res.status(400); | ||
103 | + throw new Error("openweathermap API error"); | ||
104 | + } | ||
51 | }); | 105 | }); |
52 | 106 | ||
53 | module.exports = { | 107 | module.exports = { | ... | ... |
... | @@ -8,7 +8,7 @@ const { | ... | @@ -8,7 +8,7 @@ const { |
8 | 8 | ||
9 | // "/api/weather/" | 9 | // "/api/weather/" |
10 | router.post("/", getWeather); | 10 | router.post("/", getWeather); |
11 | -router.get("/forecast", getForecast); | 11 | +router.post("/forecast", getForecast); |
12 | -router.get("/airpollution", getAirPollution); | 12 | +router.post("/airpollution", getAirPollution); |
13 | 13 | ||
14 | module.exports = router; | 14 | module.exports = router; | ... | ... |
-
Please register or login to post a comment