Realtidspriser · Uppdateras var 30:e sekund
Hur projektet byggdes
En genomgång av hur KryptoLive fungerar — från API-anrop till dynamisk rendering, sortering och automatisk uppdatering.
Målet var att bygga en live-dashboard för kryptovalutor som hämtar riktig data utan att behöva en backend eller API-nyckel. Jag ville visa priser, procentuell förändring och marknadsvärde för de 20 största kryptovalutorna.
Jag valde CoinGecko API eftersom det är gratis, kräver ingen registrering och returnerar strukturerad JSON-data med allt jag behövde — pris, volym, 1h/24h-förändring och sparkline-data för mini-grafer.
All data hämtas med JavaScripts inbyggda Fetch API — ingen extern bibliotek behövs. Anropet görs till CoinGecko:s /coins/markets-endpoint med parametrar för valuta, sparkline och prisförändringar.
const url = `https://api.coingecko.com/api/v3/coins/markets ?vs_currency=usd &ids=${COINS.join(',')} &sparkline=true &price_change_percentage=1h,24h`; const res = await fetch(url); const data = await res.json(); // Array med coin-objekt
Funktionen är async/await med try/catch för felhantering — om API:et är nere visas ett felmeddelande och gammal data behålls på skärmen.
Varje kryptovaluta renderas som ett HTML-element med hjälp av template literals och innerHTML. Funktionen renderCoin() tar ett coin-objekt och returnerar HTML-strängen.
function renderCoin(coin, idx) { const change = formatChange(coin.price_change_percentage_24h); return ` <div class="coin-card"> <div class="rank">${coin.market_cap_rank}</div> <div class="price">${formatPrice(coin.current_price)}</div> <div class="change ${change.cls}">${change.text}</div> </div>`; }
Hjälpfunktioner som formatPrice() och formatLarge() formaterar siffrorna snyggt — stora tal visas som t.ex. $1.82T och små priser med fler decimaler.
All filtrering och sortering sker lokalt i webbläsaren på den redan hämtade datan — inga nya API-anrop behövs. Sökningen filtrerar på namn och ticker-symbol i realtid.
function sortCoins(coins) { switch(currentSort) { case 'price': return [...coins].sort((a,b) => b.current_price - a.current_price); case 'change': return [...coins].sort((a,b) => b.price_change_percentage_24h - a.price_change_percentage_24h); default: // rank return [...coins].sort((a,b) => a.market_cap_rank - b.market_cap_rank); } }
Spread-operatorn ([...coins]) kopierar arrayen innan sortering så att originalordningen inte förstörs.
Sidan uppdateras automatiskt var 30:e sekund med setInterval. Timern återstartas efter varje manuell uppdatering så att den alltid räknar från senaste hämtning.
function startAutoRefresh() { clearInterval(autoRefreshTimer); // nollställ befintlig timer autoRefreshTimer = setInterval(() => { loadData(false); }, 30000); // 30 sekunder }
CoinGecko:s gratis API tillåter ~30 anrop per minut. Valet av 30 sekunders intervall håller sidan säkert inom rate-limiten utan att data ska bli inaktuell.
| Problem | Lösning |
|---|---|
| API rate-limit — för många anrop ger 429-fel | 30 sekunders intervall + felhantering som behåller gammal data vid fel |
| Priser formateras olika (Bitcoin $60 000 vs Shiba Inu $0.000012) | formatPrice() anpassar antal decimaler dynamiskt beroende på storleken |
| Myntbilder laddas ibland inte från CoinGecko | onerror-attribut döljer bilden och visar en fallback med bokstavsinitialer |
| Sortering ändrade originaldata permanent | Spread-operator kopierar arrayen före sortering så originalet bevaras |
| Tomma skärm vid laddning upplevdes som bugg | Skeleton-animation ger visuell feedback medan data hämtas |