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) =>...