CRUD
CRUD
Для взаємодії з ресурсами бекенду використовується чотири операції: створення (create), читання (read), оновлення (update) і видалення (delete). Для кожної з них визначений стандартний HTTP-метод.
GET
HTTP-метод GET використовується для отримання існуючих даних. Метод fetch() повинен відправити на сервер GET-запит без тіла. Бекенд, після отримання запиту, обробить його і у відповіді поверне необхідні ресурси.
fetch(`https://jsonplaceholder.typicode.com/posts/${postId}`) .then(response => response.json()) .then(post => console.log(post)) .catch(error => console.log(error));
POST
Метод POST використовується для додавання нового ресурсу. Метод fetch() повинен відправити POST-запит на сервер, в тілі якого буде об'єкт з полями author і body, ідентифікатор буде автоматично створений базою даних. Результатом такого запиту буде об'єкт, доданий в базу даних.
const postToAdd = { author: "Mango", body: "CRUD is awesome", }; const options = { method: "POST", body: JSON.stringify(postToAdd), headers: { "Content-Type": "application/json; charset=UTF-8", }, }; fetch("https://jsonplaceholder.typicode.com/posts", options) .then(response => response.json()) .then(post => console.log(post)) .catch(error => console.log(error));
PUT і PATCH
Методи PUT і PATCH використовуються для оновлення існуючих даних. Який метод використовувати, буде написано в документації бекенду. Бекенд, після отримання запиту, обробить його і у відповіді поверне оновлений ресурс.
const postToUpdate = { id: 1, body: "CRUD is really awesome", }; const options = { method: "PATCH", body: JSON.stringify(postToUpdate), headers: { "Content-Type": "application/json; charset=UTF-8", }, }; fetch(`https://jsonplaceholder.typicode.com/posts/${postToUpdate.id}`, options) .then(response => response.json()) .then(post => console.log(post)) .catch(error => console.log("ERROR" + error));
Метод PATCH заміняє в існуючому ресурсі значення, передані в тілі запиту властивостей. Метод PUT повністю заміняє ресурс.
DELETE
Метод DELETE використовується для видалення існуючих даних. Метод fetch() повинен відправити на сервер DELETE-запит без тіла.
const postIdToDelete = 1; fetch(`https://jsonplaceholder.typicode.com/posts/${postIdToDelete}`, { method: "DELETE", }) .then(() => console.log("Post deleted")) .catch(error => console.log("Error:", error));
Асинхронні функції async/await
Робота з бекендом може бути заплутаною - після однієї асинхронної операції необхідно зробити ще один запит на сервер на підставі отриманих даних, і так кілька разів.
const fetchFriends = () => { return fetch("my-api.com/me") .then(token => { return fetch(`my-api.com/profile?token=${token}`); }) .then(user => { return fetch(`my-api.com/users/${user.id}/friends`); }); }; fetchFriends() .then(friends => console.log(friends)) .catch(error => console.error(error));
Погодьтесь, не найзручніший для читання код, хоча операції - порівняно прості. Оскільки ми передаємо функції-обробники методу then(), утворюються ялинкоподібні вкладеності.
Асинхронні функції допомагають позбавиться колбеків і вкладених конструкцій. Водночас, вони відмінно працюють разом із методами then() і catch(), тому що гарантовано повертають проміс.
const fetchFriends = async () => { const token = await fetch("my-api.com/me"); const user = await fetch(`my-api.com/profile?token=${token}`); const friends = await fetch(`my-api.com/users/${user.id}/friends`); return friends; }; fetchFriends() .then(friends => console.log(friends)) .catch(error => console.error(error));
Синтаксис async/await
Асинхронні функції (async/await) - зручний спосіб написання асинхронного коду, який зовні стає схожим на синхронний. В основі синтаксису async/await лежать проміси, тому він не блокує основний потік виконання програми.
const fetchUsers = async () => { const response = await fetch("https://jsonplaceholder.typicode.com/users"); const users = await response.json(); return users; }; fetchUsers().then(users => console.log(users));
Коли інтерпретатор зустрічає await, він призупиняє виконання цієї функції (не тільки скрипта) і чекає, доки не виконається проміс праворуч від await. Щойно проміс виконався - виконання функції відновлюється і на рядку нижче нам доступний результат асинхронної операції.
- Оператор await можна використовувати тільки у тілі асинхронної (async) функції.
- Оператор await призупиняє функцію, доки проміс не виконається (fulfilled або rejected).
- Якщо проміс виконався успішно (fulfilled), оператор await поверне його значення.
- Якщо проміс був відхилений з помилкою (rejected), оператор await викине помилку.
- Асинхронна функція завжди повертає проміс, тому будь-яке значення, що повертається, буде його значенням.
- Якщо не вказати значення, що повертається, повернеться проміс зі значенням undefined.
Будь-яка функція може бути асинхронною, чи то метод об'єкта, класу, колбек, оголошення або інлайн функція. Всі вони зможуть використовувати оператор await і обов'язково повернуть проміс, тому що будуть асинхронними функціями.
async function foo() {} const foo = async function () {} const foo = async () => {} {getInf: async function(){}} {getInf: async () => {}}
Обробка помилок try...catch
Якщо результат асинхронної функції (проміс) не використовується у зовнішньому коді, помилки обробляються в тілі функції конструкцією try...catch. Значення параметра error в блоці catch - це помилка, яку згенерує await, якщо проміс буде відхилений.
const fetchUsers = async () => { try { const response = await fetch("https://jsonplaceholder.typicode.com/users"); const users = await response.json(); console.log(users); } catch (error) { console.log(error.message); } }; fetchUsers();
Якщо результат асинхронної функції (проміс) використовується у зовнішньому (глобальному) коді, тобто за межами інших асинхронних функцій, помилки обробляються колбеком методом catch(). Значення параметра error в методі catch() - це помилка, яку згенерує await, якщо проміс буде відхилений.
const fetchUsers = async () => { const response = await fetch("https://jsonplaceholder.typicode.com/users"); const users = await response.json(); return users; }; fetchUsers() .then(users => console.log(users)) .catch(error => console.log(error));
await можна використовувати тільки в тілі асинхронної функції.
Якщо результат асинхронної функції використовується в іншій асинхронній функції, помилки обробляються конструкцією try...catch. Значення параметра error в блоці catch - це помилка, яку згенерує await, якщо проміс буде відхилений.
const fetchUsers = async () => { const response = await fetch("https://jsonplaceholder.typicode.com/users"); const users = await response.json(); return users; }; const doStuff = async () => { try { const users = await fetchUsers(); console.log(users); } catch (error) { console.log(error.message); } }; doStuff();
Паралельні запити
Якщо одночасно необхідно зробити декілька запитів, використовувати синтаксис async/await потрібно дуже обережно. У наступному прикладі будуть виконані три послідовних запити, тому що виконання асинхронної функції призупиняється, коли інтерпретатор зустрічає await. Крім того, парс результатів запитів також буде послідовний, що забере більше часу.
const fetchUsers = async () => { const baseUrl = "https://jsonplaceholder.typicode.com"; const firstResponse = await fetch(`${baseUrl}/users/1`); const secondResponse = await fetch(`${baseUrl}/users/2`); const thirdResponse = await fetch(`${baseUrl}/users/3`); const firstUser = await firstResponse.json(); const secondUser = await secondResponse.json(); const thirdUser = await thirdResponse.json(); console.log(firstUser, secondUser, thirdUser); }; fetchUsers();
Тобто вони виконуються послідовно
У нашому випадку вони повністю незалежні, тому потрібно запустити їх паралельно. Для цього створюється масив промісів, після чого використовується метод Promise.all(), для очікування їх виконання. Масив промісів створюється методами map(), filter() тощо, залежно від завдання.
const fetchUsers = async () => { const baseUrl = "https://jsonplaceholder.typicode.com"; const userIds = [1, 2, 3]; // 1. Створюємо масив промісів const arrayOfPromises = userIds.map(async userId => { const response = await fetch(`${baseUrl}/users/${userId}`); return response.json(); }); // 2. Запускаємо усі проміси паралельно і чекаємо на їх завершення const users = await Promise.all(arrayOfPromises); console.log(users); }; fetchUsers();
За такого підходу, запити запускаються паралельно, що економить час очікування їх виконання, який дорівнює тривалості «найповільнішого» з них.
Відео Рисіч. Практика json placeholder
ресурс "json placeholder "
Переходимо в документацію: https://jsonplaceholder.typicode.com/guide/
Resources:
- /posts 100 posts
- /comments 500 comments
- /albums 100 albums
- /photos 5000 photos
- /todos 200 todos
- /users 10 users
Відкрий консоль та натискай кнопки
CODE:
const btnGetId = document.querySelector(".js-btn-getid"); btnGetId.addEventListener("click", handleGetId); function handleGetId() { return getFetchId() .then(data => console.log(data)) .catch(err => console.log(err)); } function getFetchId () { return fetch("https://jsonplaceholder.typicode.com/posts/1") .then(res => { if(!res.ok) { throw new Error(res.statusText); } return res.json(); }); }
Створення постів. Практика
- При натисканні кнопки Add post малюється форма для вводу та чіпляється слухоч подій на форму з типом "submit".
- Заповняєм поля форми і відправляєм
- Відмальовується list і Зникає форма
- Якщо помилка то відмальовується червоним текст помилки
- текст помилки зникає через 3 секунди
- Читай ще лібу по роботі з формами formData Але бекенд має бути готовим до formData. Використовується не часто
При натисканні кнопки під картинкою рендиряться пости

Тут будуть пости
Примітки
- Ніколи з функції не віддавайте готовий json!!!
- Метод PUT оновлює весь елемент (дуже рідко)
- Метод PATCH оновлює лише частину
- Ніколи з функції не віддавайте готовий json!!!
Відео Рисіч. Практика async/await
- try/catch чи then/catch?
- Приклад коду №1 (try/catch) Якщо ми опрацьовуєм http запит лише в середині функціі, і не потрібно нічого повертати з фу то достатньо try/catch.
- Приклад коду №2 (then/catch) Якщо визвати фу ззовні та робити з неї return то буде проміс. Тому потрібна Обробка then/catch
- async function завжди поверне проміс. Тому виклик такої фу тільни через then/catch
Приклад коду №1 (без return)
async function getCapital() { try { const base_CapitalURL = "https://restcountries.com/v3.1/name/Ukraine"; const resp = await fetch(base_CapitalURL); if(!resp.ok) { throw new Error(resp.statusText); } const data = await resp.json(); console.log(data); // return data; } catch(err) { console.log(err); } console.log("end"); }
Дивись консоль
Приклад коду №2 (з return)
const btnGetCapital2 = document.querySelector(".js-get-capital2"); btnGetCapital2.addEventListener("click", ()=> getCapital2() .then(data => console.log(data)) .catch(err => console.log(err)) ); async function getCapital2() { const base_CapitalURL2 = "https://restcountries.com/v3.1/name/Ukraine"; const resp = await fetch(base_CapitalURL2); if(!resp.ok) { throw new Error(resp.statusText); } return resp.json(); }
Приклад коду №3 (паралельні проміси)
const btnGetCapital3 = document.querySelector(".js-get-capital3"); btnGetCapital3.addEventListener("click", ()=> getCapital3() .then(data => { const res = data.filter(({status})=> status === "fulfilled").map(({value}) => value ) console.log(res); }) .catch(err => console.log(err)) ); async function getCapital3() { const base_CapitalURL3 = "https://restcountries.com/v3.1/name/"; const contryArr = ["Ukraine", "France", "Germany"]; const responses = contryArr.map( async (contr) => { const resp = await fetch(`${base_CapitalURL3}${contr}`); if(!resp.ok) { throw new Error("Not found"); // Promise.reject("Not found"); } return resp.json(); }) const prom = await Promise.allSettled(responses); // console.log(prom); return prom; }
Практичне завдання з розміткою. Країни, погода
- Є три інпута
- Напишемо туди три країни і дістанемо три столиці
- Відмалювати погоду для кожної з країн
- Підпис яка країна яка столиця
Зупинився на відмітці 2:15:50 VID 2
Примітки
- Ніколи з функції не віддавайте готовий json!!!
- Метод PUT оновлює весь елемент (дуже рідко)
- Метод PATCH оновлює лише частину (90%)
- axios Самостійно розібрати axios. Часто використовується