JSFiddle - React, Tailwind, and code Playground
by Sergey Kulikov
HTML
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
JavaScript
const cache = {};
const aTimeout = (t) => {
return new Promise((resolve) => {
setTimeout(resolve, t);
});
};
const getApi = async (url) => {
if (!cache[url]) {
try {
const data = await fetch(url);
const json = await data.json();
// Fix invalid API response
if (json.response === "[]") {
throw new Error("Empty response, retrying...");
}
cache[url] = json;
} catch (e) {
console.warn(e);
await aTimeout(1000);
return getApi(url);
}
}
return cache[url];
};
const getProduct = async (category) => {
const url = `https://bad-api-assignment.reaktor.com/products/${category}`;
return getApi(url);
};
const getAvailability = async (category) => {
const url = `https://bad-api-assignment.reaktor.com/availability/${category}`;
return getApi(url);
};
const merge = (arrays) => {
let result = [];
arrays.forEach((array) => {
result = result.concat(array);
});
return result;
};
const makeRow = (cb, header) => {
const row = document.createElement("tr");
const fields = ["type", "name", "price", "manufacturer", "availability"];
fields.forEach((field) => {
const cell = document.createElement(header ? "th" : "td");
cell.textContent = cb(field);
row.appendChild(cell);
});
return row;
};
const makeTable = async (data) => {
const table = document.createElement("table");
const head = makeRow((field) => field, true);
table.appendChild(head);
document.body.appendChild(table);
let i = 0;
for await (let item of data) {
i++;
if (i % 50 === 0) {
await new Promise(requestAnimationFrame);
}
const row = makeRow((field) => item[field]);
table.appendChild(row);
}
};
const main = async () => {
const categories = ["jackets", "shirts", "accessories"];
const products = await Promise.all(categories.map(getProduct));
const productsData = merge(products);
const manufacturers = productsData
.map((item) =>...