🔌 JavaScript API & Bibliotēkas
JavaScript spēks izpaužas, kad to savieno ar ārējiem datiem un bibliotēkām. Šeit iepazīsim Chart.js vizualizāciju, publiskos REST API, kā arī praktiskus Fetch API piemērus, ko var izmantot jebkurā mājaslapā.
Kas ir REST API?
REST API (Representational State Transfer) ir veids, kā serveri komunicē — atbild uz HTTP pieprasījumiem ar JSON datiem. Tieši to izmanto Fetch API, ko mācījāmies iepriekšējā nodaļā.
// Pamatprincips: nosūti HTTP pieprasījumu → saņem JSON atbildi
fetch("https://api.example.com/products")
.then(res => res.json())
.then(data => console.log(data));
// Tipiska JSON atbilde no REST API:
// {
// "status": "success",
// "data": [
// { "id": 1, "name": "Produkts A", "price": 12.99 },
// { "id": 2, "name": "Produkts B", "price": 8.50 }
// ],
// "total": 2
// }
Noderīgi bezmaksas publiskie API
Šie API ir pieejami bez reģistrācijas vai ar bezmaksas plānu — ideāli mācībām un nelieliem projektiem.
📡 Datu un satura API
- OpenWeatherMap — laika prognoze pēc pilsētas vai koordinātām. Bezmaksas: 1000 pieprasījumi/dienā.
- REST Countries — valstu dati (karogi, iedzīvotāji, valūta, valodas). Bez API atslēgas.
- JSONPlaceholder — viltus REST API testēšanai (posts, users, todos). Bez atslēgas.
- DummyJSON — produkti, lietotāji, receptes, komentāri. Pilnīgāks par JSONPlaceholder.
- Quotable — gadījuma citāti. Ātri pieviest dinamisku saturu.
- NewsAPI — jaunumi no 70 000+ avotiem. Bezmaksas izstrādātāja plāns.
- ExchangeRate API — valūtas kursi reāllaikā. 1500 pieprasījumi/mēnesī bez maksas.
- GIPHY — GIF meklēšana un iegūšana.
Chart.js — datu vizualizācija
Chart.js ir viena no populārākajām JS bibliotēkām grafikiem — viegla (~60KB), bez atkarībām, darbojas uz HTML <canvas> elementa.
<!-- Iekļaut Chart.js no CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<canvas id="manis-grafiks" width="600" height="300"></canvas>
const ctx = document.getElementById("manis-grafiks").getContext("2d");
new Chart(ctx, {
type: "bar", // "bar" | "line" | "pie" | "doughnut" | "radar" | "polarArea"
data: {
labels: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jun"],
datasets: [{
label: "Apmeklējumi",
data: [1200, 1900, 1500, 2100, 1800, 2400],
backgroundColor: [
"rgba(220, 107, 47, 0.7)", // Webpamati.lv oranžs
"rgba(220, 107, 47, 0.6)",
"rgba(220, 107, 47, 0.5)",
"rgba(220, 107, 47, 0.8)",
"rgba(220, 107, 47, 0.6)",
"rgba(220, 107, 47, 0.9)",
],
borderColor: "#dc6b2f",
borderWidth: 2,
borderRadius: 6, // Noapaļoti stabiņi
}]
},
options: {
responsive: true,
plugins: {
legend: { position: "top" },
title: {
display: true,
text: "Mājaslapas apmeklējumi 2025. gadā"
}
},
scales: {
y: { beginAtZero: true }
}
}
});
const ctx2 = document.getElementById("liniju-grafiks").getContext("2d");
// Dati no API — piemēram, no sava PHP backend
async function ieladeGrafiku() {
const resp = await fetch("/api/statistika?gads=2025");
const json = await resp.json();
new Chart(ctx2, {
type: "line",
data: {
labels: json.menesi, // ["Jan", "Feb", ...]
datasets: [
{
label: "Jauni lietotāji",
data: json.jaunie,
borderColor: "#3b82f6",
backgroundColor: "rgba(59,130,246,0.1)",
tension: 0.4, // Izliekta līnija
fill: true,
},
{
label: "Atgriežošies",
data: json.atgriesosies,
borderColor: "#dc6b2f",
backgroundColor: "rgba(220,107,47,0.1)",
tension: 0.4,
fill: true,
}
]
},
options: {
responsive: true,
interaction: {
mode: "index", // Parāda visus datus uz hover
intersect: false
}
}
});
}
ieladeGrafiku();
new Chart(document.getElementById("pirags").getContext("2d"), {
type: "doughnut",
data: {
labels: ["PHP", "JavaScript", "Python", "MySQL"],
datasets: [{
data: [35, 28, 22, 15],
backgroundColor: ["#f97316", "#eab308", "#3b82f6", "#22c55e"],
hoverOffset: 8
}]
},
options: {
plugins: {
legend: { position: "right" },
title: { display: true, text: "Populārākās valodas Webpamati.lv" }
}
}
});
// Grafiku var atjaunināt reāllaikā bez pārlādēšanas
const grafiks = new Chart(ctx, { type: "bar", data: { labels: [], datasets: [{ data: [] }] } });
function pievieno_punktu(label, vertiba) {
grafiks.data.labels.push(label);
grafiks.data.datasets[0].data.push(vertiba);
// Maksimāli rāda 10 vērtības
if (grafiks.data.labels.length > 10) {
grafiks.data.labels.shift();
grafiks.data.datasets[0].data.shift();
}
grafiks.update(); // Animēts atjauninājums
}
// Simulēt reāllaika datus
setInterval(() => {
const tagad = new Date().toLocaleTimeString("lv");
pievieno_punktu(tagad, Math.floor(Math.random() * 100));
}, 1000);
OpenWeatherMap API — laika apgabals
// 1. Reģistrēties: openweathermap.org → bezmaksas API atslēga
// 2. Pieprasījuma URL:
// https://api.openweathermap.org/data/2.5/weather?q=Riga&appid=TAVA_ATSLEGA&units=metric&lang=lv
async function iegutLaiku(pilseta) {
const API_ATSLEGA = "tava_api_atslega_seit"; // Nekad neglabā frontendā publiskā projektā!
const url = `https://api.openweathermap.org/data/2.5/weather?q=${pilseta}&appid=${API_ATSLEGA}&units=metric&lang=lv`;
try {
const atbilde = await fetch(url);
if (!atbilde.ok) throw new Error(`HTTP kļūda: ${atbilde.status}`);
const dati = await atbilde.json();
return {
pilseta: dati.name,
temp: Math.round(dati.main.temp),
juta_ka: Math.round(dati.main.feels_like),
mitrums: dati.main.humidity,
apraksts: dati.weather[0].description,
ikona: `https://openweathermap.org/img/wn/${dati.weather[0].icon}@2x.png`,
vejs: dati.wind.speed,
};
} catch (kludas) {
console.error("Laika datu kļūda:", kludas);
return null;
}
}
// Lietošana
iegutLaiku("Riga").then(laiks => {
if (!laiks) return;
document.getElementById("laika-bloks").innerHTML = `
<img src="${laiks.ikona}" alt="${laiks.apraksts}">
<h3>${laiks.pilseta}: ${laiks.temp}°C</h3>
<p>${laiks.apraksts} · Jūtas kā ${laiks.juta_ka}°C</p>
<p>💧 ${laiks.mitrums}% · 💨 ${laiks.vejs} m/s</p>
`;
});
REST Countries — valstu dati
Bez API atslēgas — ideāli karodziņu izvēlnēm, valūtas konvertētājiem, ģeogrāfiskiem filtriem.
// Visas valstis
const atbilde = await fetch("https://restcountries.com/v3.1/all?fields=name,flags,population,currencies,languages");
const valstis = await atbilde.json();
// Meklēt pēc nosaukuma
const latvija = await fetch("https://restcountries.com/v3.1/name/latvia");
const [lv] = await latvija.json();
console.log(lv.name.common); // "Latvia"
console.log(lv.name.official); // "Republic of Latvia"
console.log(lv.flags.svg); // URL uz karodziņu
console.log(lv.population); // 1850651
console.log(lv.currencies); // { EUR: { name: "Euro", symbol: "€" } }
// Renderēt karodzīnu izvēlni
async function izveidoValstusarakstu(containerId) {
const resp = await fetch("https://restcountries.com/v3.1/all?fields=name,flags,cca2");
const valstis = await resp.json();
valstis.sort((a, b) => a.name.common.localeCompare(b.name.common));
const izvele = document.getElementById(containerId);
valstis.forEach(v => {
const option = document.createElement("option");
option.value = v.cca2; // "LV"
option.textContent = `${v.flags.emoji} ${v.name.common}`;
izvele.appendChild(option);
});
}
izveidoValstusarakstu("valsts-izvele");
ExchangeRate API — valūtas kursi
// https://api.exchangerate-api.com/v4/latest/EUR ← bez atslēgas (older endpoint)
// Vai reģistrēties exchangerate-api.com priekš jaunākā versijas
async function konvertet(summa, no, uz) {
const resp = await fetch(`https://api.exchangerate-api.com/v4/latest/${no}`);
const dati = await resp.json();
const kurss = dati.rates[uz];
return (summa * kurss).toFixed(2);
}
// Lietošana
const rezultats = await konvertet(100, "EUR", "USD");
console.log(`100 EUR = ${rezultats} USD`);
// Valūtas konvertētāja forma
document.getElementById("konvertacijas-forma").addEventListener("submit", async (e) => {
e.preventDefault();
const summa = parseFloat(document.getElementById("summa").value);
const no = document.getElementById("no-valutas").value; // "EUR"
const uz = document.getElementById("uz-valutas").value; // "GBP"
const rezultats = await konvertet(summa, no, uz);
document.getElementById("rezultats").textContent = `${summa} ${no} = ${rezultats} ${uz}`;
});
Pārlūka iebūvētie API
Papildu ārējiem servisiem, pārlūks pats nodrošina vairākus noderīgus API — bez interneta savienojuma.
// ── 1. localStorage — datu glabāšana pārlūkā (paliek pēc aizvēršanas) ──
localStorage.setItem("tēma", "dark");
const tema = localStorage.getItem("tēma"); // "dark"
localStorage.removeItem("tēma");
localStorage.clear();
// Glabāt objektu (jāserializē)
const lietotajs = { vards: "Anna", valoda: "lv" };
localStorage.setItem("lietotajs", JSON.stringify(lietotajs));
const atguts = JSON.parse(localStorage.getItem("lietotajs"));
// ── 2. Geolocation API — lietotāja atrašanās vieta ──
if ("geolocation" in navigator) {
navigator.geolocation.getCurrentPosition(
(pozicija) => {
const { latitude, longitude } = pozicija.coords;
console.log(`Lat: ${latitude}, Lon: ${longitude}`);
// Apvienot ar laika API: iegutLaiku uz koordinātām
},
(kludas) => console.error("Ģeolokācija liegta:", kludas.message)
);
}
// ── 3. Clipboard API — kopēšana programmatiski ──
async function kopet(teksts) {
try {
await navigator.clipboard.writeText(teksts);
console.log("Nokopēts!");
} catch {
console.error("Clipboard piekļuve liegta");
}
}
// ── 4. Notification API — pārlūka paziņojumi ──
async function paziņot(virsraksts, teksts) {
const atlauja = await Notification.requestPermission();
if (atlauja === "granted") {
new Notification(virsraksts, {
body: teksts,
icon: "/favicon.ico"
});
}
}
// ── 5. IntersectionObserver — elements ir redzamajā laukā ──
// Izmanto: lazy loading, animācijas uz scroll, infinite scroll
const novērotājs = new IntersectionObserver((ieraksti) => {
ieraksti.forEach(ieraksts => {
if (ieraksts.isIntersecting) {
ieraksts.target.classList.add("redzams"); // Pievieno CSS klasi
novērotājs.unobserve(ieraksts.target); // Pārtraukt novērošanu
}
});
}, { threshold: 0.2 }); // 20% elementa jābūt redzamiem
// Novērot visas kartītes
document.querySelectorAll(".topic-card").forEach(el => novērotājs.observe(el));
// ── 6. Web Workers — fona aprēķini (neblocks UI) ──
// worker.js (atsevišķs fails):
// self.onmessage = (e) => {
// const rezultats = laikietilpigs_apreklinat(e.data);
// self.postMessage(rezultats);
// };
const workers = new Worker("worker.js");
workers.postMessage({ dati: [1, 2, 3, 4, 5] });
workers.onmessage = (e) => console.log("Rezultāts:", e.data);
Pilns piemērs: laika sīkrīks
Apvienojam OpenWeatherMap API, Geolocation API un Chart.js vienā funkcionālā komponentā.
<div id="laika-sikriks">
<p id="laika-stavoklis">Notiek lokācijas noteikšana...</p>
<div id="laika-info" hidden></div>
<canvas id="temp-grafiks" width="400" height="150" hidden></canvas>
</div>
const API_KEY = "tava_api_atslega";
async function ieladeLatika() {
const statuss = document.getElementById("laika-stavoklis");
statuss.textContent = "Notiek lokācijas noteikšana...";
// 1. Iegūt koordinātas
const pozicija = await new Promise((resolve, reject) =>
navigator.geolocation.getCurrentPosition(resolve, reject)
);
const { latitude: lat, longitude: lon } = pozicija.coords;
statuss.textContent = "Ielādē laika datus...";
// 2. Iegūt tagadējo laiku
const [laiksResp, prognozeResp] = await Promise.all([
fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric&lang=lv`),
fetch(`https://api.openweathermap.org/data/2.5/forecast?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric&cnt=8`)
]);
const laiks = await laiksResp.json();
const prognoze = await prognozeResp.json();
// 3. Renderēt pašreizējo laiku
document.getElementById("laika-info").innerHTML = `
<h3>📍 ${laiks.name}: ${Math.round(laiks.main.temp)}°C</h3>
<p>${laiks.weather[0].description}</p>
`;
document.getElementById("laika-info").hidden = false;
statuss.hidden = true;
// 4. Renderēt 24h temperatūras grafiku ar Chart.js
const canvas = document.getElementById("temp-grafiks");
canvas.hidden = false;
new Chart(canvas.getContext("2d"), {
type: "line",
data: {
labels: prognoze.list.map(p =>
new Date(p.dt * 1000).toLocaleTimeString("lv", { hour: "2-digit", minute: "2-digit" })
),
datasets: [{
label: "Temperatūra (°C)",
data: prognoze.list.map(p => Math.round(p.main.temp)),
borderColor: "#dc6b2f",
backgroundColor: "rgba(220,107,47,0.1)",
tension: 0.4,
fill: true
}]
},
options: { responsive: true, plugins: { legend: { display: false } } }
});
}
ieladeLatika().catch(err => {
document.getElementById("laika-stavoklis").textContent = `Kļūda: ${err.message}`;
});