DarslarWeb dasturlash
Amaliy loyiha 2 — Ob-havo app (API bilan)
Real ochiq API bilan ishlash: shahar bo'yicha ob-havo ma'lumoti. async/await amaliyoti.
70 daqiqa
JavaScript — Dars 20
Yakuniy loyiha: Ob-havo app
fetch, async/await, error handling va zamonaviy UI. Haqiqiy API bilan ishlashni o'rganasiz.
fetchasyncAPIJSON
Bosqichlar
6 ta mavzu1. API haqida
Open-Meteo — ro'yxatdan o'tish shart bo'lmagan, bepul ob-havo API. Biz undan foydalanamiz.
1// 1-qadam: Shahar nomidan koordinata2// https://geocoding-api.open-meteo.com/v1/search?name=Tashkent&count=13
4// 2-qadam: Koordinatadan ob-havo5// https://api.open-meteo.com/v1/forecast?latitude=41.3&longitude=69.27¤t=temperature_2m,weather_code,wind_speed_10m6
7// Javob misoli:8{9 "current": {10 "time": "2026-04-18T14:00",11 "temperature_2m": 22.4,12 "weather_code": 1,13 "wind_speed_10m": 3.214 }15}2. HTML va CSS
1<!DOCTYPE html>2<html lang="uz">3<head>4 <meta charset="UTF-8">5 <title>Ob-havo</title>6 <link rel="stylesheet" href="style.css">7</head>8<body>9 <div class="card">10 <h1>Ob-havo</h1>11 <form id="f">12 <input type="text" id="shahar" placeholder="Shahar" required>13 <button>Ko'rish</button>14 </form>15 <div id="out"></div>16 </div>17 <script src="app.js"></script>18</body>19</html>1body { font-family: system-ui, sans-serif; background: linear-gradient(#1e3a8a, #0f172a); color: white; min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; margin: 0; }2.card { background: rgba(255,255,255,.1); backdrop-filter: blur(10px); padding: 30px; border-radius: 20px; max-width: 400px; width: 100%; }3h1 { text-align: center; margin: 0 0 18px; }4form { display: flex; gap: 8px; margin-bottom: 20px; }5input { flex: 1; padding: 12px 14px; border: none; border-radius: 10px; background: rgba(255,255,255,.15); color: white; font-size: 15px; }6button { padding: 12px 18px; border: none; border-radius: 10px; background: #fbbf24; color: #0f172a; font-weight: 700; cursor: pointer; }7.temp { font-size: 64px; font-weight: 800; text-align: center; }8.desc { text-align: center; opacity: .8; margin-bottom: 14px; }9.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-top: 14px; }10.it { background: rgba(255,255,255,.1); padding: 10px 12px; border-radius: 10px; }11.err { color: #fca5a5; text-align: center; padding: 12px; }3. fetch bilan so'rov
app.js
1const form = document.getElementById("f");2const inp = document.getElementById("shahar");3const out = document.getElementById("out");4
5form.addEventListener("submit", async (e) => {6 e.preventDefault();7 const nom = inp.value.trim();8 if (!nom) return;9
10 out.innerHTML = '<div>Yuklanmoqda...</div>';11
12 try {13 const geo = await koordinataOl(nom);14 if (!geo) {15 out.innerHTML = '<div class="err">Shahar topilmadi</div>';16 return;17 }18 const havo = await havoniOl(geo.latitude, geo.longitude);19 chiz(geo, havo);20 } catch (err) {21 out.innerHTML = '<div class="err">Xato: ' + err.message + '</div>';22 }23});24
25async function koordinataOl(nom) {26 const url = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(nom)}&count=1`;27 const res = await fetch(url);28 if (!res.ok) throw new Error("Geocoding xato");29 const data = await res.json();30 return data.results ? data.results[0] : null;31}32
33async function havoniOl(lat, lon) {34 const url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}¤t=temperature_2m,weather_code,wind_speed_10m,relative_humidity_2m`;35 const res = await fetch(url);36 if (!res.ok) throw new Error("Ob-havo xato");37 return await res.json();38}4. Natijani ko'rsatish
1const havoKodi = {2 0: "Ochiq osmon",3 1: "Asosan ochiq",4 2: "Qisman bulutli",5 3: "Bulutli",6 45: "Tuman",7 51: "Nam tomchilar",8 61: "Yomg'ir",9 63: "Kuchli yomg'ir",10 71: "Qor",11 95: "Momaqaldiroq",12};13
14function chiz(geo, havo) {15 const c = havo.current;16 const tavsif = havoKodi[c.weather_code] || "Ob-havo";17
18 out.innerHTML = `19 <div>20 <div style="text-align:center; opacity:.8">${geo.name}, ${geo.country}</div>21 <div class="temp">${Math.round(c.temperature_2m)}°</div>22 <div class="desc">${tavsif}</div>23 <div class="grid">24 <div class="it">Shamol: ${c.wind_speed_10m} km/s</div>25 <div class="it">Namlik: ${c.relative_humidity_2m}%</div>26 </div>27 </div>28 `;29}5. Xato ushlash
1// Qaysi xatolar bo'lishi mumkin?2
3// 1. Tarmoq xatosi (internet yo'q)4try {5 const res = await fetch(url);6} catch (e) {7 // TypeError: Failed to fetch8}9
10// 2. HTTP status 4xx/5xx11const res = await fetch(url);12if (!res.ok) throw new Error(`HTTP ${res.status}`);13
14// 3. Bo'sh javob15const data = await res.json();16if (!data.results || data.results.length === 0) {17 throw new Error("Shahar topilmadi");18}6. Jonli demo
Ob-havo app
Natijajonli
Portfolio uchun
Shu loyihani GitHub'ga qo'ying va Vercel'da deploy qiling. CV uchun ajoyib.
Keyingi qadam
React/Next.js'ga o'ting. U bilan bu app'ni tezroq va toza yozib bo'lardi.