Amaliy loyiha 2 — Ob-havo app (API bilan)

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 mavzu
  1. 01API haqida
  2. 02HTML va CSS
  3. 03fetch bilan so'rov
  4. 04Natijani ko'rsatish
  5. 05Xato ushlash
  6. 06Jonli demo

1. API haqida

Open-Meteo — ro'yxatdan o'tish shart bo'lmagan, bepul ob-havo API. Biz undan foydalanamiz.

1// 1-qadam: Shahar nomidan koordinata
2// https://geocoding-api.open-meteo.com/v1/search?name=Tashkent&count=1
3
4// 2-qadam: Koordinatadan ob-havo
5// https://api.open-meteo.com/v1/forecast?latitude=41.3&longitude=69.27&current=temperature_2m,weather_code,wind_speed_10m
6
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.2
14 }
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}&current=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 fetch
8}
9
10// 2. HTTP status 4xx/5xx
11const res = await fetch(url);
12if (!res.ok) throw new Error(`HTTP ${res.status}`);
13
14// 3. Bo'sh javob
15const 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.

Yakuniy vazifa

0 / 6