Day 18: Data Fetch + Render (API or local JSON)
Build a component that fetches data from an API or local JSON file, then renders that data into the page as a list of repeated UI items while handling loading and error states.
JavaScript focus
- fetching async data
- waiting for a response
- converting response data into usable JavaScript
- looping through returned items
- creating DOM elements from data
- appending rendered items into a container
- handling loading, success, and error states
Nice extras
- use createElement() instead of innerHTML
- limit the number of items rendered if the dataset is large
- include a thumbnail/image if the data provides one
- include an empty state if no items are returned
- keep the render logic in its own function
- keep the fetch logic in its own function
- add a loading class or status message while waiting
- use a reusable card pattern that fits your site
MDN prep
Data Fetch + Render
The HTML
<!-- createElements with JavaScript -->
<div class="grid_articles">
<!-- loop/forEach the items here -->
<article class="article">
<figure class="figure">
<img src="https://picsum.photos/400/250?random=1" alt="Accessible Modal Dialog">
</figure>
<h3>Accessible Modal Dialog</h3>
<p>A reusable modal component built with semantic HTML and vanilla JavaScript.</p>
<a href="#" target="_blank">Read more...</a>
</article>
</div>
The JavaScript
async function fetchData() {
try {
const response = await fetch("../data/projects.json");
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
return data;
} catch (error) {
console.error("There was a problem with the fetch: ", error);
}
}
async function initFetchAndRender() {
const data = await fetchData();
if (!data) return;
const root = document.querySelector(".fetch_render");
if (!root) return;
const grid = document.createElement("div");
grid.classList.add("grid_articles");
root.append(grid);
data.forEach((item) => {
const article = document.createElement("article");
const figure = document.createElement("figure");
const img = document.createElement("img");
const h3 = document.createElement("h3");
const p = document.createElement("p");
const link = document.createElement("a");
article.classList.add("article");
figure.classList.add("figure");
img.src = item.image;
img.alt = item.title;
h3.textContent = item.title;
p.textContent = item.description;
link.href = item.url;
link.target = "_blank";
link.textContent = "Read more...";
figure.append(img);
article.append(figure, h3, p, link);
grid.append(article);
});
}
initFetchAndRender();