nmk

Лабораторне заняття №13 (2 години). Інтеграція з публічними API.

Мета

Нарешті відмовитися від “заглушок” (mock-даних) і навчитися отримувати реальну інформацію з віддалених серверів Інтернету. Опанувати Fetch API для здійснення HTTP-запитів (GET) та обробку JSON-відповідей для наповнення інтернет-магазину реальними товарами.

План

  1. Знайомство з FakeStoreAPI.
  2. Використання fetch() та async / await для запиту списку товарів.
  3. Обробка відповідей (конвертація у JSON).
  4. Заміна старого локального масиву products на завантажені дані.
  5. Налаштування обробки помилок мережі (якщо сервер впав).

Хід роботи

Увага: Заключний етап Ванільного JavaScript. “TechShop” перетворюється на справжній клієнт серверного додатку.

  1. Огляд API:
    • Відкрийте в браузері нову вкладку і перейдіть за адресою: https://fakestoreapi.com/products?limit=8.
    • Ви побачите “сирий” JSON-формат даних (масив справжніх товарів: електроніка, одяг, прикраси, зі справжніми фотографіями та цінами в доларах).
    • Саме цей масив ми і маємо завантажити у наш скрипт.
  2. Модифікація функції fetchProducts (main.js):
    • У Практичній №11 ви написали симуляцію сервера через setTimeout. Тепер ми її видалимо.
    • Ми напишемо справжній запит до серверу:

      // Старий масив `const products = [...]` ми БІЛЬШЕ НЕ ВИКОРИСТОВУЄМО. Закоментуйте його.
      
      // Нова функція завантаження:
      async function fetchProducts() {
        try {
          // 1. Надсилаємо мережевий GET-запит
          const response = await fetch(
            "https://fakestoreapi.com/products?limit=8",
          );
      
          // 2. Перевіряємо чи статус відповіді ОК (200-299)
          if (!response.ok) {
            throw new Error(`HTTP помилка: ${response.status}`);
          }
      
          // 3. Розпаковуємо тіло відповіді з JSON у звичайний масив JavaScript
          const realProducts = await response.json();
      
          // Розкоментуйте, щоб побачити масив у консолі:
          // console.log("Дані з сервера:", realProducts);
      
          // Повертаємо масив, щоб ним міг скористатися initShop()
          return realProducts;
        } catch (error) {
          console.error("Помилка завантаження товарів:", error.message);
          // Прокидаємо помилку далі, щоб спінер зник і користувач побачив "Помилка мережі"
          throw error;
        }
      }
      
  3. Оновлення глобального стану кошика:
    • Оскільки ми видалили наш старий масив products, функція перехоплення кліку (яка шукає товар через products.find) буде видавати помилку “products is not defined”.
    • Вирішення: Вам треба створити глобальну змінну let globalStoreProducts = [];, заповнити її після того, як initShop отримав data, і в події кліку “Купити” шукати товар вже по globalStoreProducts.
  4. Оновлення HTML-генератора:
    • Ваш код htmlString = data.map(...) у функції initShop потрібно злегка змінити, оскільки тепер у JSON-даних інші назви полів (наприклад ціна тепер у доларах).
    • Змініть product.price грн на $${product.price} (вставте знак долара).
    • У img src вставте ${product.image} (на щастя, API також віддає картинку саме у цьому полі).
  5. Збереження (Commit & Push):
    • Оновіть сторінку. Ви повинні побачити реальні товари, а не заглушки від PlaceHolder! Додавання до кошика має працювати як і раніше (рахуючи вже долари).
    • Виконайте git add . та git commit -m "Fetch real products from FakeStoreAPI using Fetch".
    • Запушіть у свою гілку та злийте в main.

Результат

Інтернет-магазин повністю інтегрований із зовнішнім світом. Він завантажує дані через Інтернет, перетворює JSON і будує інтерфейс динамічно так, як це роблять Amazon, Розетка чи Prom.

Контрольні питання

  1. В чому різниця між протоколом передачі даних (HTTP) та форматом збереження даних (JSON)? Як вони взаємодіють під час виконання методу fetch()?
  2. Що станеться, якщо URL в функції fetch('htt://nepravylniy-url.com') буде зламаний? (Хто спіймає помилку і де ми це побачимо у нашому скрипті?)
  3. Чому ми застосовуємо метод await response.json() замість звичайного response.text() чи простого використання змінної response без методів? Що фізично зберігається у “сирому” response?
  4. Які основні методи (verbs) HTTP-запитів ви знаєте, крім GET? Чому за замовчуванням fetch() робить саме GET?
  5. Для чого більшість публічних API (як-от FakeStoreAPI, Weather API) використовують ключі доступу (API Keys) і чому ми в нашому тестовому API обійшлися без нього?