JavaScript Foundations • StreetGeek Academy
🧠 MODULE 9: Fetch API, Async/Await & Local Storage
Learn how to connect your website to external data sources using the Fetch API, handle asynchronous code with async/await,
and store/retrieve data locally using the browser’s Storage APIs.
1) What Is the Fetch API?
The Fetch API lets you make network requests (like loading data from an API) using a simple syntax.
Think of it as: “Go get this data → wait for it → then show it on the page.”
Basic Example
fetch("https://api.github.com/users/SitesByYogi")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("Error:", error));
2) Using Async/Await (Modern Syntax)
Instead of chaining .then() calls, you can write cleaner, synchronous-style code using
async/await.
async function getUser() {
try {
const response = await fetch("https://api.github.com/users/SitesByYogi");
const data = await response.json();
console.log(data);
} catch (error) {
console.error("Error fetching data:", error);
}
}
getUser();
await pauses until the Promise resolves — only usable inside an async function.
3) Displaying API Data on Your Portfolio
Let’s fetch your latest GitHub repos and show them on your Projects page.
HTML
<section id="github-projects">
<h2>Latest GitHub Projects</h2>
<ul id="repo-list"></ul>
</section>
JavaScript
async function loadRepos() {
const repoList = document.getElementById("repo-list");
try {
const response = await fetch("https://api.github.com/users/SitesByYogi/repos");
const repos = await response.json();
repoList.innerHTML = ""; // clear existing list
repos.slice(0, 5).forEach(repo => {
const li = document.createElement("li");
li.innerHTML = `<a href="${repo.html_url}" target="_blank">${repo.name}</a>`;
repoList.appendChild(li);
});
} catch (error) {
repoList.innerHTML = "<li>⚠️ Unable to load projects.</li>";
}
}
loadRepos();
4) Local Storage — Saving Data in the Browser
localStorage is like a tiny database built into your browser.
It stores key-value pairs that persist even after refreshing or closing the browser.
Example
localStorage.setItem("theme", "dark"); // Save data
const theme = localStorage.getItem("theme"); // Retrieve data
console.log(theme); // "dark"
Remove or Clear
localStorage.removeItem("theme");
localStorage.clear(); // deletes all items
5) Example: Remember Dark Mode Preference
HTML
<button id="theme-toggle">🌙 Toggle Theme</button>
JavaScript
const toggleBtn = document.getElementById("theme-toggle");
const body = document.body;
// Apply saved theme on load
if (localStorage.getItem("theme") === "dark") {
body.classList.add("dark");
}
// Toggle and save theme
toggleBtn.addEventListener("click", () => {
body.classList.toggle("dark");
const mode = body.classList.contains("dark") ? "dark" : "light";
localStorage.setItem("theme", mode);
});
6) Session Storage (Temporary Storage)
Similar to localStorage, but data is erased when the tab closes.
sessionStorage.setItem("sessionUser", "Yogi");
console.log(sessionStorage.getItem("sessionUser"));
7) Fetching and Rendering JSON Data (Local File)
You can also load a local .json file instead of an API.
data/projects.json
[
{ "title": "Portfolio", "tech": "HTML/CSS/JS" },
{ "title": "ShopBlocks", "tech": "PHP/WooCommerce" }
]
JavaScript
async function loadLocalProjects() {
const response = await fetch("data/projects.json");
const data = await response.json();
console.table(data);
}
loadLocalProjects();
8) Handling Loading & Error States
Users shouldn’t see a blank section — show loading and fallback messages.
const repoList = document.getElementById("repo-list");
repoList.innerHTML = "<li>⏳ Loading projects...</li>";
try {
const response = await fetch("https://api.github.com/users/SitesByYogi/repos");
const repos = await response.json();
// render data...
} catch (err) {
repoList.innerHTML = "<li>❌ Failed to fetch data.</li>";
}
9) Combining Fetch + Storage (Practical)
Cache data locally to avoid re-fetching every time.
async function getRepos() {
const cached = localStorage.getItem("repos");
if (cached) {
console.log("Loaded from cache");
return JSON.parse(cached);
}
console.log("Fetching from API...");
const response = await fetch("https://api.github.com/users/SitesByYogi/repos");
const data = await response.json();
localStorage.setItem("repos", JSON.stringify(data));
return data;
}
getRepos().then(data => console.log(data));
10) Quiz Time
Show/Hide Questions
1) What does the Fetch API do?
2) What’s the difference between .then() and async/await?
3) What’s the difference between localStorage and sessionStorage?
4) What’s the best way to handle API errors gracefully?
5) How do you convert a JSON response into a JavaScript object?
🚀 Challenge Task — Live Data + Preferences Integration
Enhance your Portfolio Projects section with:
- A “Load Projects” button that fetches from your GitHub automatically.
- A loading spinner or text while fetching.
- A theme toggle that saves the user’s choice in
localStorage. - A “Last Updated” timestamp stored and retrieved from
localStorage.
Bonus: Store fetched repos for 24 hours
const now = Date.now();
localStorage.setItem("repos", JSON.stringify({
time: now,
data: repos
}));
const cached = JSON.parse(localStorage.getItem("repos"));
if (cached && now - cached.time < 86400000) { // 24 hours in ms
renderRepos(cached.data);
}
🏁 Module 9 Summary
- How to use the Fetch API to load external or local data
- How to handle async code with
async/await - How to save and retrieve data using
localStorage - How to handle API errors and loading states gracefully
- How to combine live data with stored preferences
Next up → MODULE 10: Final Project — Interactive Portfolio v2.0
You’ll integrate everything you’ve learned — DOM manipulation, events, fetch, storage — into one cohesive interactive experience.