//fetch basic / fetch improved function fetchBasic(element, jsonStr) { let table = document.createElement('table'); table.style.fontFamily = 'sans-serif'; for (const key in jsonStr) { let tr = document.createElement('tr'); let tdKey = document.createElement('th'); let tdValue = document.createElement('td'); tdKey.textContent = key; if(typeof jsonStr[key] === 'string' && jsonStr[key].includes('https://swapi.dev/api/')) { let button = document.createElement('button'); button.textContent = jsonStr[key]; button.onclick = () => { fetch(jsonStr[key]) .then(res => res.json()) .then(luke => fetchBasic(tdValue, luke)); } button.style.border = 'transparent'; button.style.backgroundColor = 'transparent'; button.style.fontSize = '16px' button.style.padding = '0' button.style.cursor = 'pointer' tdValue.append(button); } else if(Array.isArray(jsonStr[key])) { jsonStr[key].forEach((item) =>{ if (typeof item === 'string' && item.includes('https://swapi.dev/api/')){ let button = document.createElement('button'); button.textContent = item; button.onclick = () => { fetch(item) .then(res => res.json()) .then(luke => fetchBasic(tdValue, luke)); } button.style.border = 'transparent'; button.style.backgroundColor = 'transparent'; button.style.fontSize = '16px' button.style.padding = '0' button.style.cursor = 'pointer' tdValue.append(button); } else { tdValue.append = item } }) } else if(typeof jsonStr[key] === 'object' && jsonStr[key] !== null){ for (const key in jsonStr[key]) { let obj = document.createElement('p'); obj.textContent = `${key}: ${jsonStr[key]}`; tdValue.append(obj) } } else{ tdValue.textContent = jsonStr[key]; } tr.append(tdKey); tr.append(tdValue); table.append(tr); for (let cell of tr.cells) { cell.style.border = '2px solid #000'; cell.style.padding = '10px'; cell.style.textAlign = 'left'; cell.classList.add('td'); } } element.append(table); } fetch('https://swapi.dev/api/people/1/') .then(res => res.json()) .then(luke => fetchBasic(containerForm, luke)); //myfetch function myfetch(url){ return new Promise(function (resolve, reject){ let xhr = new XMLHttpRequest(); xhr.open("GET", url, true); xhr.send(); xhr.onload = () => xhr.status !== 200 ? reject() : resolve(JSON.parse(xhr.responseText)); xhr.onerror = () => reject(); }) } myfetch('https://swapi.dev/api/people/1/') .then(luke => console.log(luke), () => console.log('Error:')) //race const delay = ms => new Promise(ok => setTimeout(() => ok(ms), ms)); Promise.race([myfetch('https://swapi.dev/api/people/1/'), delay(2080)]) .then(value => console.log(value), () => console.log('Error'));