Praktiska Övningar: Asynkron JavaScript och API-Anrop
Nu är det dags att praktisera de kraftfulla koncept vi har lärt oss i detta kapitel. Vi kommer att använda fetch
för att hämta data från det publika test-API:et JSONPlaceholder och sedan bearbeta och visa den datan med hjälp av array-metoder och DOM-manipulation.
Förutsättningar:
- En enkel HTML-fil (
index.html
) där du kan visa resultaten. - En länkad JavaScript-fil (
script.js
) där du skriver din kod. - Grundläggande kunskaper i DOM-manipulation (t.ex.
querySelector
,createElement
,textContent
,appendChild
) från föregående kapitel.
Tips: Använd async/await
för att hantera dina fetch
-anrop, då det ofta ger mer läsbar kod. Glöm inte try...catch
för felhantering!
Övning 1: Hämta och Visa Användare
Mål: Hämta en lista med användare från JSONPlaceholder och visa deras namn i en lista på webbsidan.
- Skapa HTML-struktur: Lägg till en
<ul>
-tagg i dinindex.html
med ett id, t.ex.id="user-list"
. - Hämta Användare (i
script.js
):- Skapa en
async function
, t.ex.fetchUsers()
. - Använd
fetch
för att göra ett GET-anrop tillhttps://jsonplaceholder.typicode.com/users
. - Hantera
response
-objektet: Kontrolleraresponse.ok
och användawait response.json()
för att få datan. - Använd
try...catch
för att fånga eventuella fel under hämtningen.
- Skapa en
- Visa Namnen:
- Inuti
fetchUsers()
(efter att du har fått datan): Hämta referensen till din<ul>
-tagg. - Loopa igenom arrayen med användardata (som du fick från API:et).
- För varje användare, skapa ett nytt
<li>
-element. - Sätt
<li>
-elementetstextContent
till användarensname
. - Lägg till (
appendChild
)<li>
-elementet i din<ul>
.
- Inuti
- Anropa Funktionen: Glöm inte att anropa din
fetchUsers()
-funktion så att koden körs när sidan laddas. - Testa: Öppna
index.html
i webbläsaren. Ser du en lista med 10 användarnamn?
Övning 2: Filtrera och Mappa Todos
Mål: Hämta en lista med "todos" (att-göra-uppgifter) från JSONPlaceholder. Filtrera listan så att du bara har de slutförda (completed: true
) uppgifterna. Visa titlarna på dessa slutförda uppgifter i en ny lista.
- Skapa HTML-struktur: Lägg till en ny
<ul>
-tagg, t.ex.id="completed-todos"
. - Hämta Todos (i
script.js
):- Skapa en ny
async function
, t.ex.fetchAndFilterTodos()
. - Använd
fetch
för att hämta data frånhttps://jsonplaceholder.typicode.com/todos
. - Hantera
response
och parsa JSON som i övning 1, inkluderatry...catch
.
- Skapa en ny
- Filtrera och Mappa:
- När du har fått todo-arrayen:
- Använd
filter()
-metoden för att skapa en ny array som endast innehåller de objekt där egenskapencompleted
ärtrue
. - Använd
map()
-metoden på den filtrerade arrayen för att skapa en ny array som endast innehållertitle
för varje slutförd todo.
- Använd
- När du har fått todo-arrayen:
- Visa Titlarna:
- Hämta referensen till din
<ul>
-tagg (#completed-todos
). - Loopa igenom arrayen med titlar.
- Skapa och lägg till
<li>
-element för varje titel i<ul>
.
- Hämta referensen till din
- Anropa Funktionen: Anropa
fetchAndFilterTodos()
. - Testa: Öppna
index.html
. Ser du en lista med titlarna på de slutförda uppgifterna?
Övning 3: Kombinera Data (Post och Kommentarer)
Mål: Hämta först en specifik bloggpost (t.ex. post med id 5). När du har hämtat posten, använd dess id
för att hämta alla kommentarer som hör till just den posten. Visa postens titel och sedan en lista med kommentarernas namn (namnet på den som kommenterat).
- Skapa HTML-struktur: Lägg till en
<div>
, t.ex.id="post-and-comments"
. - Hämta Data (i
script.js
):- Skapa en
async function
, t.ex.fetchPostAndComments(postId)
. - Steg 1: Hämta Posten:
- Använd
fetch
för att hämta data frånhttps://jsonplaceholder.typicode.com/posts/${postId}
(använd template literal för att inkluderapostId
). - Hantera
response
och parsa JSON. Spara post-objektet.
- Använd
- Steg 2: Hämta Kommentarer:
- Använd
fetch
igen, nu för att hämta data frånhttps://jsonplaceholder.typicode.com/posts/${postId}/comments
(ellerhttps://jsonplaceholder.typicode.com/comments?postId=${postId}
). - Hantera
response
och parsa JSON. Spara kommentars-arrayen.
- Använd
- Använd
try...catch
för att hantera fel från båda anropen.
- Skapa en
- Visa Resultatet:
- Hämta referensen till din
<div>
(#post-and-comments
). - Skapa och lägg till ett
<h2>
-element med postenstitle
. - Skapa en
<ul>
-lista för kommentarerna. - Loopa igenom kommentars-arrayen.
- För varje kommentar, skapa ett
<li>
-element med kommentarensname
och lägg till det i<ul>
. - Lägg till
<ul>
-listan i din<div>
.
- Hämta referensen till din
- Anropa Funktionen: Anropa
fetchPostAndComments(5)
(eller välj ett annat id). - Testa: Öppna
index.html
. Ser du postens titel följt av en lista med namn på de som kommenterat?
Övning 4: Felhantering med Fetch
Mål: Öva på att hantera olika typer av fel som kan uppstå vid fetch
-anrop.
- Försök hämta från en ogiltig URL:
- Skapa en
async function
. - Försök att
fetch
från en URL som inte finns, t.ex.https://jsonplaceholder.typicode.com/nonexistent-endpoint
. - Använd
try...catch
. Vad händer icatch
-blocket? Logga felet. - Kontrollera också
response.ok
inutitry
-blocket (även om du kanske inte kommer dit om URL:en är helt fel). Visa ett felmeddelande på sidan omresponse.ok
ärfalse
eller om ettcatch
-fel inträffar.
- Skapa en
- Försök parsa ogiltig JSON:
- Hämta data från en URL som inte returnerar JSON, t.ex.
https://google.com
(detta kan ge CORS-problem, testa annars med en lokal fil eller en URL du vet returnerar HTML). - Försök att anropa
await response.json()
på svaret. - Se till att ditt
try...catch
-block fångar felet som uppstår vid JSON-parsningen. Logga felet och visa ett användarvänligt meddelande på sidan.
- Hämta data från en URL som inte returnerar JSON, t.ex.
Övning 5 (Bonus): Aggregera Data med Reduce
Mål: Hämta alla "posts" från JSONPlaceholder och använd reduce
för att räkna hur många poster varje userId
har skrivit.
- Hämta Alla Poster:
- Skapa en
async function
. - Hämta data från
https://jsonplaceholder.typicode.com/posts
. - Hantera
response
och parsa JSON.
- Skapa en
- Räkna Poster per Användare:
- Använd
reduce()
-metoden på post-arrayen. - Ditt
initialValue
ska vara ett tomt objekt{}
. - I din reducer-funktion, för varje
post
:- Kontrollera om
post.userId
redan finns som en nyckel i ackumulator-objektet (accumulator
). - Om det finns, öka värdet (antalet) med 1.
- Om det inte finns, lägg till
post.userId
som en nyckel med värdet 1. - Returnera det uppdaterade ackumulator-objektet.
- Kontrollera om
- Använd
- Visa Resultatet:
- Logga det slutliga objektet som
reduce
returnerar. Det bör se ut ungefär så här:{ '1': 10, '2': 10, '3': 10, ... }
. - (Valfritt) Visa denna information på webbsidan på ett snyggt sätt.
- Logga det slutliga objektet som
Dessa övningar ger dig en bra grund för att arbeta med asynkron kod och externa API:er i dina framtida JavaScript-projekt!