All Tracks/lab weather app/
Đang tải...
Hướng dẫn thử thách
1 / 1

Build a Weather App

In this lab, you'll build an app that provides weather information from different cities. You will use a weather API. The output data has the following format: ```json { "weather": [ { "main": "Clear", "description": "clear sky", "icon": "https://cdn.freecodecamp.org/weather-icons/01n.png" // icon representing the weather } ], "main": { "temp": 2.62, // temperature in C "feels_like": 0.84, // temperature in C "temp_min": 1.72, // min temperature of the day in C "temp_max": 3.49, // max temperature of the day in C "pressure": 1010, // atmospheric pressure in hPa "humidity": 81 // humidity in % }, "visibility": 10000, // distance in meters "wind": { "speed": 1.79, // speed of the wind in m/s "deg": 285, // orientation of the wind in degrees "gust": 3.13 // gust speed in m/s }, "name": "London" } ``` **Objective:** Fulfill the user stories below and get all the tests to pass to complete the lab. **User Stories:** 1. You should have a `button` element with an `id` of `get-weather-btn`. 1. You should have a `select` element with seven `option` elements nested within it. The first option should have an empty string as its text and `value` attribute. The rest should have the following for their text and values (with the value being lowercase): - New York - Los Angeles - Chicago - Paris - Tokyo - London 1. If no city is selected, pressing the button should do nothing. 1. If a city is selected, elements to show the weather should appear: - You should have an `img` element with the id `weather-icon` for displaying the weather icon. - You should have an element with the id `main-temperature` for displaying the main temperature. - You should have an element with the id `feels-like` for displaying what the temperature feels like. - You should have an element with the id `humidity` for displaying the amount of humidity in air. - You should have an element with the id `wind` for displaying the wind speed. - You should have an element with the id `wind-gust` for displaying the wind gust. - You should have an element with the id `weather-main` for displaying the main weather type. - You should have an element with the id `location` for displaying the current location. 1. You should have an asynchronous function named `getWeather` that fetches the weather information from the `https://weather-proxy.freecodecamp.rocks/api/city/<CITY>` API and returns it. Note that this API returns data using the metric system, that means m/s for wind speed, and Celsius for the temperature. 1. The `getWeather` asynchronous function should accept a city as its argument. 1. You should handle any errors that occur within the `getWeather` function and log them to the console. 1. You should have an asynchronous `showWeather` function that accepts a city as parameter. 1. The `showWeather` function should call the `getWeather` function to retrieve the weather data for the selected city from the dropdown. 1. If the `getWeather` function had an error, the app should only show an alert that says `Something went wrong, please try again later`. 1. If the data from `getWeather` are usable, the `showWeather` function should display the weather data in the corresponding elements. If a certain value from the API is `undefined`, you should write `N/A` in the corresponding element. **Note:** Neither the `getWeather` function nor the `showWeather` function should be declared using `const`, since the tests need to reassign them. Also, the tests will take time to complete, so as long as you see `// running tests` in the console, they are being executed. # --before-all-- ```js window.fetch = (url) => { const city = decodeURIComponent(url.split("/").pop()); const cityMap = { "new york": { coord: { lon: -74.0059, lat: 40.7127 }, weather: [ { id: 804, main: "Clouds", description: "overcast clouds", icon: "https://cdn.freecodecamp.org/weather-icons/04d.png", }, ], base: "stations", main: { temp: 14.33, feels_like: 13.2, temp_min: 13.21, temp_max: 15.54, pressure: 1008, humidity: 53, sea_level: 1008, grnd_level: 1007, }, visibility: 10000, wind: { speed: 3.6, deg: 40 }, clouds: { all: 100 }, dt: 1732123426, sys: { type: 1, id: 4610, country: "US", sunrise: 1732103363, sunset: 1732138471, }, timezone: -18000, id: 5128581, name: "New York", cod: 200, }, "los angeles": { coord: { lon: -118.2437, lat: 34.0522 }, weather: [ { id: 800, main: "Clear", description: "clear sky", icon: "https://cdn.freecodecamp.org/weather-icons/01d.png", }, ], base: "stations", main: { temp: 17.24, feels_like: 15.88, temp_min: 14.84, temp_max: 19.62, pressure: 1023, humidity: 33, sea_level: 1023, grnd_level: 1003, }, visibility: 10000, wind: { speed: 2.57, deg: 70 }, clouds: { all: 0 }, dt: 1732123664, sys: { type: 2, id: 2075946, country: "US", sunrise: 1732113063, sunset: 1732150008, }, timezone: -28800, id: 5368361, name: "Los Angeles", cod: 200, }, chicago: { coord: { lon: -87.6298, lat: 41.8781 }, weather: [ { id: 802, main: "Clouds", description: "scattered clouds", icon: "https://cdn.freecodecamp.org/weather-icons/03d.png", }, ], base: "stations", main: { temp: 8.91, feels_like: 4.91, temp_min: 7.86, temp_max: 9.44, pressure: 1009, humidity: 50, sea_level: 1009, grnd_level: 987, }, visibility: 10000, wind: { speed: 9.39, deg: 285, gust: 12.52 }, clouds: { all: 40 }, dt: 1732123645, sys: { type: 2, id: 2010190, country: "US", sunrise: 1732106817, sunset: 1732141557, }, timezone: -21600, id: 4887398, name: "Chicago", cod: 200, }, london: { coord: { lon: -0.1278, lat: 51.5074 }, weather: [ { id: 800, main: "Clear", description: "clear sky", icon: "https://cdn.freecodecamp.org/weather-icons/01n.png", }, ], base: "stations", main: { temp: 2.62, feels_like: 0.84, temp_min: 1.72, temp_max: 3.49, pressure: 1010, humidity: 81, sea_level: 1010, grnd_level: 1005, }, visibility: 10000, wind: { speed: 1.79, deg: 285, gust: 3.13 }, clouds: { all: 1 }, dt: 1732123462, sys: { type: 2, id: 2075535, country: "GB", sunrise: 1732087658, sunset: 1732118707, }, timezone: 0, id: 2643743, name: "London", cod: 200, }, tokyo: { coord: { lon: 139.6917, lat: 35.6895 }, weather: [ { id: 501, main: "Rain", description: "moderate rain", icon: "https://cdn.freecodecamp.org/weather-icons/10n.png", }, ], base: "stations", main: { temp: 8.71, feels_like: 5.38, temp_min: 8.08, temp_max: 9.81, pressure: 1015, humidity: 92, sea_level: 1015, grnd_level: 1014, }, visibility: 7000, wind: { speed: 6.69, deg: 330 }, rain: { "1h": 2.05 }, clouds: { all: 75 }, dt: 1732123711, sys: { type: 2, id: 268395, country: "JP", sunrise: 1732137787, sunset: 1732174284, }, timezone: 32400, id: 1850144, name: "Tokyo", cod: 200, }, }; return Promise.resolve({ ok: city !== "paris", json: () => Promise.resolve(cityMap[city]), }); }; // function that construct an object with the id-value pairs that we expect in the page from an object const helper = (wobj) => ({ "weather-icon": wobj.weather[0].icon, "main-temperature": wobj.main.temp || "N/A", "feels-like": wobj.main.feels_like || "N/A", humidity: wobj.main.humidity || "N/A", wind: wobj.wind.speed || "N/A", "wind-gust": wobj.wind.gust || "N/A", "weather-main": wobj.weather[0].main || "N/A", location: wobj.name || "N/A", }); const timeout = milliseconds => new Promise(resolve => { return setTimeout(resolve, milliseconds) }); ```
Vượt qua bài kiểm tra hiện tại để mở khóa bài tiếp theo.
main.sh
UTF-8 • Tab Size: 2Kiểm tra bài:⌘↵
Test Output
Thử thách này không có bài test tự động. Hãy quan sát kết quả trực tiếp ở khung Preview.