// Javascript Async: Promise Homework
// fetch basic
// -------------УСЛОВИЕ-------------
// С помощью следующего кода считать и вывести информацию о Люке Скайвокере:
// fetch('https://swapi.dev/api/people/1/')
// .then(res => res.json())
// .then(luke => console.log(luke))
// Напишите функцию для отображения любого JSON в форме таблицы. Функция должна принимать два параметра:
// DOM - элемент, в котором строится таблица
// JSON, который нужно отобразить.
// -------------РЕШЕНИЕ-------------
const task02block = document.createElement('div');
task02block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px";
const task02title = document.createElement('h2');
task02title.innerText = 'Task-02 Fetch basic';
root.appendChild(task02block);
task02block.appendChild(task02title);
function drawTable(block, JSONdata) {
const heroTable = document.createElement('table');
heroTable.innerHTML = "";
heroTable.border = "1";
heroTable.style.maxWidth="1000px";
heroTable.insertAdjacentHTML('beforeend', '
Hero portfolio');
const heroTableHead = document.createElement('tr');
const heroTableBody= document.createElement('tr');
heroTableHead.innerHTML = Object.keys(JSONdata).map(key => `${key} | `).join('');
heroTableBody.innerHTML = Object.values(JSONdata).map(item => `${item} | `).join('').split(',').join(', ');
heroTable.appendChild(heroTableHead);
heroTable.appendChild(heroTableBody);
block.appendChild(heroTable);
}
let url1 = 'https://swapi.dev/api/people/1/';
fetch(url1)
.then(res => res.json())
.then(luke => drawTable(task02block, luke))
// fetch improved
// -------------УСЛОВИЕ-------------
// Расширить функцию отображения:
// Если одно из полей строка или массив.
// Если строки или строка содержат в себе https://swapi.dev/api/, то выводить вместо текста строки кнопку, при нажатии на которую:
// делается fetch данных по этой ссылке
// функция отображения запускает сама себя(рекурсивно) для отображения новых данных в том же элементе.
// -------------РЕШЕНИЕ-------------
const task03block = document.createElement('div');
task03block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px";
const task03title = document.createElement('h2');
const task03fetchBlock = document.createElement('div');
task03title.innerText = 'Task-03 Fetch improved';
root.appendChild(task03block);
task03block.appendChild(task03title);
task03block.appendChild(task03fetchBlock);
function drawTableImproved(block, JSONdata, url) {
block.innerHTML = '';
const link = 'https://swapi.dev/api/';
const heroTable = document.createElement('table');
heroTable.innerHTML = "";
heroTable.border = "1";
heroTable.style.maxWidth="1000px";
let caption=url.split('/')[4];
heroTable.insertAdjacentHTML('beforeend', `${caption[0].toUpperCase() + caption.slice(1)}`);
const heroTableHead = document.createElement('tr');
const heroTableBody= document.createElement('tr');
heroTableHead.innerHTML = Object.keys(JSONdata).map(key => `${key} | `).join('');
for (let item of Object.values(JSONdata)) {
const tableBodyCell = document.createElement('td');
if (isNaN(item)&&item.includes(link)) {
const btnBodyCell = document.createElement('button');
btnBodyCell.style.margin = '5px';
btnBodyCell.value = item;
btnBodyCell.innerText = "Go to";
url = item;
btnBodyCell.onclick = () => {fetchFunc( btnBodyCell.value)};
tableBodyCell.appendChild(btnBodyCell);
}
else {
if (Array.isArray(item) && item.filter(elem => elem.includes(link)).length) {
let i = 1;
for (let subItem of item) {
const btnBodyCell = document.createElement('button');
btnBodyCell.style.margin = '5px';
btnBodyCell.value = subItem;
btnBodyCell.innerText = 'Go to ' + i;
url=subItem;
btnBodyCell.onclick = () => {fetchFunc(btnBodyCell.value)};
tableBodyCell.appendChild(btnBodyCell);
i++;
}
}
else { tableBodyCell.innerText = item; }
}
heroTableBody.appendChild(tableBodyCell);
}
heroTable.appendChild(heroTableHead);
heroTable.appendChild(heroTableBody);
block.appendChild(heroTable);
}
let url = 'https://swapi.dev/api/people/1/';
function fetchFunc(url) {
fetch(url)
.then(res => res.json())
.then(luke => drawTableImproved(task03fetchBlock, luke, url))
}
fetchFunc(url);
// myfetch
// -------------УСЛОВИЕ-------------
// Используя XMLHTTPRequest, напишите промисифицированную функцию myfetch, т.е.функцию, которая возвращает промис,
// и работает схоже с fetch, только в один этап:
// myfetch('https://swapi.dev/api/people/1/')
// .then(luke => console.log(luke))
// Функция myfetch ожидает что ответ будет в формате JSON(используйте JSON.parse(response.text))
// В случае ошибок(request.onerror или request.status не 200) не забудьте вызывать reject
// function myfetch(url){
// return new Promise(function (resolve, reject){
// const xhr = new XMLHTTPRequest()
// ///...
// })
// }
// -------------РЕШЕНИЕ-------------
const task04block = document.createElement('div');
task04block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px";
const task04title = document.createElement('h2');
const task04fetchBlock = document.createElement('div');
task04title.innerText = 'Task-04 My fetch';
root.appendChild(task04block);
task04block.appendChild(task04title);
task04block.appendChild(task04fetchBlock);
function myfetch(url) {
return new Promise(function(resolve, reject) {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
if (this.status == 200) {
resolve(JSON.parse(xhr.responseText));
} else {
var error = new Error(this.statusText);
error.code = this.status;
alert(error);
reject(error);
}
};
xhr.onerror = function() {reject(new Error("Network Error"));
};
xhr.send();
});
}
myfetch(url)
.then(luke => {
console.log(luke);
drawTableImproved(task04fetchBlock, luke, url)
}
);
// race
// -------------УСЛОВИЕ-------------
// Используя Promise.race запустите запрос на API(myfetch) параллельно с delay.
// По результату определите, что было быстрее, запрос по сети, или определенный интервал времени.
// Подберите параметр delay так, чтобы результат был неизвестен изначально, и при многократных запусках быстрее был то delay,
// то myfetch.
// -------------РЕШЕНИЕ-------------
const task05block = document.createElement('div');
task05block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px";
const task05title = document.createElement('h2');
const task05fetchBlock = document.createElement('div');
task05title.innerText = 'Task-05 race';
const runPromisesBtn = document.createElement('button');
runPromisesBtn.innerText = 'Run promises';
runPromisesBtn.style = 'margin-bottom:20px';
root.appendChild(task05block);
task05block.appendChild(task05title);
task05block.appendChild(runPromisesBtn);
task05block.appendChild(task05fetchBlock);
runPromisesBtn.onclick = () => {
task05fetchBlock.innerHTML = '';
const delay = async (ms) => await new Promise((resolve, reject) => setTimeout(() => resolve('2-nd promise'), ms));
Promise.race([myfetch(url), delay(100)]).then((value) => {
console.log(value);
const firstPromise = document.createElement('p');
firstPromise.innerText = `Faster was ${JSON.stringify(value)}`;
task05fetchBlock.appendChild(firstPromise);
})
}