Lekce 12 - AJAX v JavaScriptu - Prohlížeč pokémonů
V minulé lekci, AJAX v JavaScriptu - Základní dotazy, jsme si zkusili základní použití technologie AJAX na našem novém projektu prohlížeče pokémonů. Stáhli jsme si data o pokémonech z webového API.
V dnešním tutoriálu OOP v JavaScriptu budeme pokračovat s tvorbou prohlížeče pokémonů pomocí AJAXu.
Odpověď serveru
Zaměřme se nyní na vrácená data ve formátu JSON. Odpověď serveru vypadá následovně (již jsme ji viděli, tak ji zde zkrátíme a také lépe naformátujeme):
{ "count":964, "next":"https://pokeapi.co/api/v2/pokemon?offset=20&limit=20", "previous":null, "results": [ {"name":"bulbasaur","url":"https://pokeapi.co/api/v2/pokemon/1/"}, {"name":"ivysaur","url":"https://pokeapi.co/api/v2/pokemon/2/"}, ..., {"name":"raticate","url":"https://pokeapi.co/api/v2/pokemon/20/"} ] }
Hned první položka (count
) na vráceném objektu nám říká,
že již existuje neuvěřitelných 964 pokémonů. Nejvíce nás zajímá pole
results
, kde jsou objekty se jmény pokémonů a adresami na API s
jejich detaily. Jak to, že je v poli ale pouze 20 pokémonů, když jich je
celkem skoro 1000? Není to chyba, je to tím, že zdroj na této URL se chová
tak, že vrátí pouze prvních 20 pokémonů, aby nezatěžoval server. V
položce next
nám navíc nabídne URL, která načte 20
následujících pokémonů. Zpravidla totiž nepotřebujeme uživateli zobrazit
1000 položek najednou, místo toho API očekává, že je budeme načítat
průběžně (třeba při scrollování stránkou dolů). Pokud bychom chtěli
stáhnout všechny pokémony najednou, musíme upravit parametr
limit
v URL:
https://pokeapi.co/api/v2/pokemon?limit=1000
.
Prohlížeč pokémonů
Nyní tedy umíme stahovat data a je jen na nás, jak s nimi naložíme. Pojďme si naprogramovat jednoduchý prohlížeč pokémonů.
Funkce stahniJSON()
Budeme již dělat více requestů, proto si to zjednodušíme novou funkcí
stahniJSON()
. Náš dosavadní kód v souboru
obsluha.js
tedy smažeme a přidáme si definici nové funkce
stahniJSON()
:
function stahniJSON(url, callback) { const xhr = new XMLHttpRequest(); xhr.onload = () => { callback(JSON.parse(xhr.response)); }; xhr.open("GET", url); xhr.send(); }
Funkce jen obaluje vytvoření, otevření a odeslání požadavku, abychom nemuseli psát pokaždé to samé znovu. Přijímá dva parametry:
url
– Adresa, ze které chceme stáhnout data.callback
– Funkce, kterou voláme po úspěšném stažení dat ze serveru. Stažená data této funkci předáváme parametrem.
Všimněme si parsování JSON do objektu pomocí JSON.parse()
,
protože odpovědí serveru je text.
HTML kostra
Připravíme si základní HTML kostru stránky, do které budeme AJAXem
stahovat seznam pokémonů a následně dokonce zobrazovat detaily vybraného
pokémona, včetně jeho obrázku Budeme tedy potřebovat jeden
<div>
pro seznam
pokémonů a jeden pro detaily jednoho pokémona. Oba obalíme třetím
elementem <div>
a vložíme na začátek elementu
<body>
souboru index.html
:
<div id="poke-container"> <div id="poke-seznam"></div> <div id="poke-detaily"></div> </div>
Načítání pokémonů
Nyní budeme potřebovat další dvě funkce – nactiSeznam()
a
nactiPokemona()
, které stáhnou data a přepíšou obsah na
stránce. Pojďme si je naprogramovat.
Načtení seznamu
Do souboru obsluha.js
tedy vložíme další funkci
nactiSeznam()
s následujícím kódem:
function nactiSeznam(url) { const seznamDivElement = document.getElementById("poke-seznam"); seznamDivElement.innerHTML = "<ul id='poke-seznam-ul'></ul>"; const seznamElement = document.getElementById("poke-seznam-ul"); stahniJSON(url, (data) => { for (const pokemon of data.results) { const urlPokemona = pokemon.url; const tlacitko = document.createElement("button"); tlacitko.innerHTML = pokemon.name; tlacitko.onclick = () => { nactiPokemona(urlPokemona); }; const novaPolozka = document.createElement("li"); novaPolozka.appendChild(tlacitko); seznamElement.appendChild(novaPolozka); } }); }
Funkce v parametru přijímá adresu API, ze kterého budeme stahovat data. V
těle funkce si nejprve vytváříme element seznamu, do kterého pokémony
vypíšeme. Jde o základní práci s DOM elementy. Samotné pokémony
následně stahujeme pomocí naší funkce stahniJSON()
. Té
předáváme adresu API a anonymní funkci,
která se zavolá po úspěšném stažení dat.
Tato anonymní funkce má pouze jeden parametr s objektem obsahujícím
stažená data. Pokémoni jsou obsaženi ve vlastnosti results
.
Pokémony procházíme cyklem a pro každého vytváříme položku seznamu s
tlačítkem. Každému tlačítku přidáváme obsluhu události
onclick
, ve které voláme funkci nactiPokemona()
s
patřičnou URL získanou z dat API.
Každé API pochopitelně odpovídá ve specifickém formátu a musíme si nastudovat, jak s ním pracovat.
Načtení detailu pokémona
Podívejme se, jak vypadá JSON s detailem nějakého pokémona, což nám
osvětlí, jaká data přenést do naší aplikace. Kvůli všem útokům
pokémona a jejich detailům je JSON opravdu vyčerpávající, pro naše
účely si tyto části uvádět nebudeme, níže jsou nahrazeny třemi tečkami
...
:
{ "abilities": [ ... ], "base_experience": 64, "forms": [ ... ], "game_indices": [ ... ], "height": 7, "held_items": [], "id": 1, "is_default": true, "location_area_encounters": "https://pokeapi.co/api/v2/pokemon/1/encounters", "moves": [ ... ] } ], "name": "bulbasaur", "order": 1, "species": { "name": "bulbasaur", "url": "https://pokeapi.co/api/v2/pokemon-species/1/" }, "sprites": { "back_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png", "back_female": null, "back_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png", "back_shiny_female": null, "front_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png", "front_female": null, "front_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/1.png", "front_shiny_female": null }, "stats": [ ... ], "types": [ { "slot": 2, "type": { "name": "poison", "url": "https://pokeapi.co/api/v2/type/4/" } }, { "slot": 1, "type": { "name": "grass", "url": "https://pokeapi.co/api/v2/type/12/" } } ], "weight": 69 }
Výše vidíme JSON pro Bulbasaura, konkrétně stažený z URL
https://pokeapi.co/api/v2/pokemon/1/
, kde parametr 1
udává číslo pokémona. Zajímá nás zejména vlastnost name
s
názvem pokémona, sprites
s jeho obrázky, height
s
výškou a weight
s váhou dané potvůrky. Samozřejmě bychom
mohli i vypsat například typy pokémona, vidíme, že zrovna Bulbasaur je
jedovatý a zároveň travní typ.
V souboru obsluha.js
si vytvoříme další funkci posílající
dotaz na konkrétního pokémona s následujícím kódem:
function nactiPokemona(url) { const detailyDivElement = document.getElementById("poke-detaily"); stahniJSON(url, (data) => { detailyDivElement.innerHTML = ` <img src="${data.sprites.front_default}" /> <ul> <li>Název: ${data.name}</li> <li>Výška: ${data.height}</li> <li>Váha: ${data.weight}</li> </ul> `; }); }
Zavolání načtení seznamu
Vše máme připraveno. Stačí již jen jako poslední řádek našeho javascriptového souboru zavolat načtení seznamu:
nactiSeznam("https://pokeapi.co/api/v2/pokemon");
CSS styly
Aby náš prohlížeč vypadal trochu líbivěji, přidáme si ještě
nějaké CSS styly. Ve složce css/
si vytvoříme soubor
styly.css
s následujícím kódem:
#poke-container { display: flex; gap: 2rem; } #poke-detaily { text-align: center; margin-left: 10px; } #poke-container ul { list-style-type: none; margin: 0; padding: 0; } #poke-seznam li button { width: 100%; padding: 5px 20px; background-color: #e0ffe0; cursor: pointer; border: 0; border-bottom: 1px solid green; } #poke-seznam li button:hover { background-color: green; }
Nezapomeneme si je samozřejmě nalinkovat v hlavičce souboru
index.html
:
<head> <meta charset="UTF-8"> <title>Prohlížeč pokémonů</title> <link href="css/styly.css" rel="stylesheet"> </head>
Interaktivní ukázka
Výsledek bude vypadat takto:
Po kliknutí na položku se načtou základní informace o pokémonovi a obrázek.
Tímto možnosti API s pokémony opravdu nekončí Jak sami vidíte, API pokémonů je
velmi chytré a všude nám nabízí další URL, přes které se dostaneme k
dalším datům, třeba k abilitám.
V příští lekci, AJAX v JavaScriptu - POST a další HTTP dotazy, pošleme AJAX požadavky pro ukládání a zpracování dat a ukážeme si jak zpracovat chyby.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 345x (2.86 kB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript