# 20 - AJAX a Fetch API ## 🎯 Co se naučíte V této lekci se naučíte načítat data z externích API pomocí Fetch API. ## 📚 Témata lekce - **AJAX** - Asynchronous JavaScript and XML - **Fetch API** - moderní způsob načítání dat - **Promises** - asynchronní operace - **async/await** - čistší syntax pro asynchronní kód - **JSON API** - práce s REST API - **Pokémon API** - praktická ukázka (pokeapi.co) - **JSONPlaceholder** - testovací API (jsonplaceholder.typicode.com) - **Error handling** - ošetření chyb při načítání ## 📂 Soubory v projektu - `index.html` - rozcestník - `pokemon.html` - práce s Pokémon API - `todofetch.html` - práce s Todo API - JavaScript soubory pro fetch operace ## 💻 Základní Fetch ### Fetch - Promise syntax: ```javascript // Načtení dat z API fetch('https://pokeapi.co/api/v2/pokemon/pikachu') .then(response => response.json()) // Převod na JSON .then(data => { console.log(data); // Práce s daty document.getElementById("name").textContent = data.name; }) .catch(error => { console.error('Chyba:', error); alert('Nepodařilo se načíst data'); }); ``` ### Fetch - async/await syntax (modernější): ```javascript async function loadPokemon() { try { const response = await fetch('https://pokeapi.co/api/v2/pokemon/pikachu'); const data = await response.json(); console.log(data); document.getElementById("name").textContent = data.name; document.getElementById("image").src = data.sprites.front_default; } catch (error) { console.error('Chyba:', error); alert('Nepodařilo se načíst data'); } } // Volání funkce loadPokemon(); ``` ## 🚀 Jak s lekcí pracovat 1. Otevřete `index.html` v prohlížeči 2. Klikněte na "Práce s Pokémon API" 3. Sledujte načítání dat z API 4. Otevřete **Console** (F12) - uvidíte API odpovědi 5. Vyzkoušejte "Práce s TodoList API" 6. Prozkoumejte JavaScript kód - jak funguje fetch 7. Zkuste změnit URL API a načíst jiná data ## 💡 Tip pro studenty ### Fetch API kroky: 1. **Zavolat fetch()** s URL 2. **Počkat na response** (.then nebo await) 3. **Převést na JSON** (.json()) 4. **Použít data** (zobrazit, zpracovat) 5. **Ošetřit chyby** (.catch nebo try/catch) ### GET request (načtení dat): ```javascript fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)); ``` ### POST request (odeslání dat): ```javascript fetch('https://api.example.com/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ title: 'Nový úkol', completed: false }) }) .then(response => response.json()) .then(data => console.log('Vytvořeno:', data)) .catch(error => console.error('Chyba:', error)); ``` ### Async/Await pattern: ```javascript async function getData() { try { const response = await fetch(url); // Kontrola, zda je response OK if (!response.ok) { throw new Error('Network response was not ok'); } const data = await response.json(); return data; } catch (error) { console.error('Error:', error); throw error; } } // Použití getData() .then(data => console.log(data)) .catch(error => console.error(error)); ``` ### Loading indicator: ```javascript async function loadData() { // Zobrazit loading document.getElementById("loading").style.display = "block"; try { const response = await fetch(url); const data = await response.json(); // Zpracovat data displayData(data); } catch (error) { console.error(error); } finally { // Skrýt loading document.getElementById("loading").style.display = "none"; } } ``` ## 🎯 Praktické příklady ### Pokémon API: ```javascript async function loadPokemon(name) { const url = `https://pokeapi.co/api/v2/pokemon/${name}`; const response = await fetch(url); const pokemon = await response.json(); // Zobrazení dat document.getElementById("pokemonName").textContent = pokemon.name; document.getElementById("pokemonImage").src = pokemon.sprites.front_default; document.getElementById("pokemonType").textContent = pokemon.types[0].type.name; document.getElementById("pokemonWeight").textContent = pokemon.weight; } // Volání loadPokemon("pikachu"); ``` ### JSONPlaceholder - Todo API: ```javascript async function loadTodos() { const response = await fetch('https://jsonplaceholder.typicode.com/todos'); const todos = await response.json(); // Zobrazit prvních 10 todos const ul = document.getElementById("todoList"); todos.slice(0, 10).forEach(todo => { const li = document.createElement("li"); li.className = todo.completed ? "completed" : ""; li.textContent = todo.title; ul.appendChild(li); }); } ``` ## 🌐 Užitečná testovací API - **JSONPlaceholder**: https://jsonplaceholder.typicode.com/ - Fake REST API pro testování - Todos, posts, users, comments - **PokeAPI**: https://pokeapi.co/ - Pokémon data - Obrázky, statistiky, typy - **OpenWeather API**: https://openweathermap.org/api - Počasí (vyžaduje API klíč) - **Cat Facts API**: https://catfact.ninja/fact - Náhodné fakty o kočkách ## ⚠️ Důležité poznámky 1. **CORS** - některá API mohou blokovat requesty z prohlížeče 2. **API klíče** - některá API vyžadují registraci a klíč 3. **Rate limiting** - omezení počtu requestů 4. **async funkce** vrací vždy Promise 5. **await** lze použít pouze v async funkci 6. **try/catch** vždy použijte pro error handling ## 🔗 Související lekce - **Předchozí:** - 19_todolist - Todo list aplikace - 11_json - práce s JSON - **Související:** API integrace v reálných projektech - **Dokumentace:** - [Fetch API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) - [Async/Await - MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)