Welcome back to our journey into the browser's hidden superpowers! So far, we've learned why Web APIs are essential (Part 1) and how to manipulate the page with the DOM API (Part 2). Our applications are now interactive, but they have a problem: they have no memory and can't talk to the outside world.
Today, we're giving our browser a backpack. This backpack has two pockets:
- A walkie-talkie to communicate with servers anywhere on the internet. This is the Fetch API.
- A notebook to jot down information and remember it later. This is the Web Storage API.
Mastering these two APIs will elevate your vanilla JavaScript projects from simple toys to full-fledged applications.
Your Walkie-Talkie: The Fetch API
For years, developers used a clunky tool called XMLHttpRequest
(often nicknamed "XHR") to make network requests. It was powerful but had a complicated and unintuitive syntax.
The Fetch API is its modern, powerful, and much cleaner replacement. It's based on Promises, which makes handling asynchronous operations (like waiting for a server to respond) a breeze.
Making a GET
Request (Fetching Data)
Let's fetch some user data from the free JSONPlaceholder API, just like we previewed in Part 1.
The async/await
syntax is the cleanest way to work with Promises. Let's break down the process.
// A function to fetch and display users
async function fetchUsers() {
const userList = document.querySelector('#user-list');
try {
// 1. "await" the response from the server
const response = await fetch('https://jsonplaceholder.typicode.com/users');
// 2. Check if the response was successful (status 200-299)
if (!response.ok) {
// If not, throw an error to be caught by the catch block
throw new Error(`Network response was not ok: ${response.statusText}`);
}
// 3. The response body is a stream. We need to parse it as JSON.
// This is also an asynchronous operation, so we "await" it.
const users = await response.json();
// 4. Now we have the data! We can use our DOM skills from Part 2.
users.forEach(user => {
const li = document.createElement('li');
li.textContent = user.name;
userList.append(li);
});
} catch (error) {
// If anything goes wrong in the try block, it gets caught here.
console.error('Fetch error:', error);
userList.textContent = 'Failed to load users.';
}
}
// Call the function
fetchUsers();
That's it! In a few lines of readable code, we've made a network request, handled potential errors, parsed the data, and updated the DOM. No libraries needed.
Making a POST
Request (Sending Data)
What about sending data to a server? Fetch handles this elegantly too. We just need to pass a second argument: an options object.
async function createUser(userData) {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST', // Specify the HTTP method
headers: {
// Tell the server we're sending JSON
'Content-Type': 'application/json'
},
// The data we're sending, converted to a JSON string
body: JSON.stringify(userData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = await response.json();
console.log('Successfully created user:', result);
} catch (error) {
console.error('Error creating user:', error);
}
}
// Example usage:
const newUser = {
name: 'Jane Doe',
username: 'janedoe99',
email: 'jane@example.com'
};
createUser(newUser);
Your Notebook: The Web Storage API
Okay, we can fetch data. But what if the user refreshes the page? Our beautiful list of users disappears. We need a way to store information in the browser itself.
The Web Storage API provides a simple, persistent key-value store. It comes in two flavors.
1. localStorage
Think of localStorage
as a permanent notebook. Data saved here persists even after the browser is closed and reopened. It's perfect for saving user settings (like a "dark mode" preference) or a JWT token for authentication.
The API is incredibly simple:
-
localStorage.setItem('key', 'value')
: Save a value. -
localStorage.getItem('key')
: Retrieve a value. -
localStorage.removeItem('key')
: Delete a value. -
localStorage.clear()
: Delete everything.
Important: localStorage
can only store strings. If you want to store a JavaScript object, you must convert it to a string with JSON.stringify()
first, and parse it back with JSON.parse()
when you retrieve it.
Example: Saving a theme preference.
const themeToggleButton = document.querySelector('#theme-toggle');
// On page load, check if a theme is saved in localStorage
const savedTheme = localStorage.getItem('theme');
if (savedTheme) {
document.body.classList.add(savedTheme);
}
themeToggleButton.addEventListener('click', () => {
document.body.classList.toggle('dark-mode');
// After toggling, save the current state
if (document.body.classList.contains('dark-mode')) {
localStorage.setItem('theme', 'dark-mode');
} else {
localStorage.removeItem('theme'); // Or set it to 'light-mode'
}
});
2. sessionStorage
sessionStorage
is like a sticky note for the current browser tab. It has the exact same API as localStorage
(setItem
, getItem
, etc.), but with one key difference: the data is cleared when the tab is closed.
It's perfect for storing temporary information that shouldn't stick around forever, like data for a multi-page form or the state of a shopping cart before checkout.
A Glimpse into the Future: IndexedDB
For simple key-value pairs, localStorage
is perfect. But what if you need to store large amounts of structured data and query it efficiently, like a real database? For that, the browser provides IndexedDB. It’s a full-fledged, transactional, client-side database. It’s significantly more complex than localStorage
, but it's the right tool for building powerful offline-first applications. We won't cover it in detail here, but it's the next logical step in your data storage journey.
What's Next?
Our application is getting smart. It can control the page (DOM), talk to servers (Fetch), and remember things (Web Storage). It's starting to feel like a real app.
But we can push it further. We can make it interact with the user's physical world.
In Part 4, we'll bridge the digital-physical divide by exploring Device APIs. We'll get the user's location, pop up system notifications, and interact with their clipboard!
Top comments (0)