Peppa Pig Boss Battle
3-level Peppa Pig battle game with a power-up menu.
PeppaPigGame: Web APIs Lesson (with Snippets)
Big Goal
Build a game feature powered by a live API, following this flow:
- Request data with Fetch API
- Parse JSON safely
- Use the result in gameplay (here: API music in PeppaPigGame)
Foundation: What are Web APIs?
What is an API?
An API (Application Programming Interface) is a set of rules that let one software system ask another system for data or perform actions. Think of it like a restaurant menu:
- You (the client) look at the menu (the API’s documentation)
- You order something (make an API request)
- The kitchen processes your order (the server handles the request)
- You get your food back (the server sends back a response)
Web APIs specifically live on the internet. Your JavaScript code in the browser can request data from a web server somewhere else in the world.
Real-world example: iTunes Search API
In this lesson, we use iTunes Search API:
- URL:
https://itunes.apple.com/search - Input: A search term (e.g., “peppa pig theme”)
- Output: JSON data with music tracks, artists, preview URLs, artwork, etc.
How the Internet Works (Simple Version)
The Request-Response Cycle
- You send a request: Browser -> Server (over HTTP)
- Server processes it: Finds matching data
- Server sends a response: Server -> Browser (over HTTP)
- You use the data: JavaScript code processes the response
HTTP Status Codes
When a server responds, it includes a status code that tells you what happened:
200= OK, request succeeded404= Not found, server can’t find that resource500= Server error, something went wrong403= Forbidden, you don’t have permission
Why this matters in code: Always check the status before using the response data.
Part 1: The Fetch API (How to make requests)
What is the Fetch API?
fetch() is a built-in JavaScript function that makes HTTP requests. It’s the modern, preferred way to get data from APIs.
Basic syntax:
What fetch does:
- Sends an HTTP request to the given URL
- Returns a Promise (a value that will be ready later)
- Lets you handle success (
.then()) or failure (.catch())
%%js
fetch(url)
.then(response => { /* handle response */ })
.catch(error => { /* handle error */ });
Building the Request URL
APIs need parameters to know what to search for. URLs can have query parameters (the part after ?):
Why encodeURIComponent()? Spaces and special characters break URLs. This function converts "peppa pig theme" into "peppa%20pig%20theme" (safe for URLs).
%%js
const filter = "peppa pig theme";
const url = "https://itunes.apple.com/search?term=" + encodeURIComponent(filter);
console.log(url);
Part 2: Understanding the Response
What does fetch() return?
When the server responds, fetch() gives you a Response object with:
.status= the HTTP status code.json()= a method that converts the response body to JavaScript data.text()= a method that gets the response as plain text
Validating the Status
Always check if the request succeeded before using the data:
Breaking this down:
fetch()makes the request- First
.then()checks if status is 200 - If not, throw an error (stops execution)
- If yes,
.json()parses the response body - Second
.then()receives the parsed data .catch()handles any errors
%%js
const url = "https://itunes.apple.com/search?term=" + encodeURIComponent("peppa pig theme");
fetch(url, { method: 'GET', mode: 'cors' })
.then(response => {
if (response.status !== 200) {
throw new Error('Database response error: ' + response.status);
}
return response.json();
})
.then(data => {
console.log('Track count:', data.results.length);
})
.catch(err => console.error(err));
Part 3: Understanding JSON
What is JSON?
JSON (JavaScript Object Notation) is a text format for storing data. It looks like JavaScript objects but is just plain text.
Example JSON response from iTunes API:
{
"results": [
{
"artistName": "The Wiggles",
"trackName": "Peppa Pig Theme",
"artworkUrl100": "https://example.com/image.jpg",
"previewUrl": "https://example.com/preview.mp4"
},
{
"artistName": "Kids TV",
"trackName": "Peppa Pig Song",
"artworkUrl100": "https://example.com/image2.jpg",
"previewUrl": "https://example.com/preview2.mp4"
}
]
}
Extracting Data from JSON
Once you have JSON data, you access it like a normal JavaScript object:
Key takeaway: JSON is just structured data. Once parsed, you use it like any JavaScript object.
%%js
const data = {
results: [
{ artistName: 'The Wiggles', trackName: 'Peppa Pig Theme', artworkUrl100: 'https://example.com/image.jpg', previewUrl: 'https://example.com/preview.mp4' }
]
};
for (const row of data.results) {
const artist = row.artistName;
const track = row.trackName;
const imageUrl = row.artworkUrl100;
const previewUrl = row.previewUrl;
console.log(artist, track, imageUrl, previewUrl);
}
Part 4: The Audio API (Playing Sound)
What is the Audio API?
The Audio API is a built-in browser interface for creating and controlling audio playback. It’s simple but powerful.
Creating an audio element:
Why async/await? Playing audio is asynchronous (it takes time). await pauses execution until the promise resolves.
%%js
const previewUrl = 'https://example.com/song.mp4';
const audio = new Audio(previewUrl);
audio.volume = 0.35;
audio.loop = true;
audio.play().catch(err => console.warn('Autoplay blocked until user gesture:', err));
Part 5: Putting It Together (Game Integration)
Architecture: Separating Concerns
Good code separates API logic from game logic. Create a controller class:
Benefits:
- Reusable: Call
startMusic()from anywhere - Testable: Each method does one thing
- Maintainable: Changes to API logic are isolated
%%js
class PeppaMusicApiController {
constructor(endpoint) {
this.endpoint = endpoint;
}
async fetchPreviewUrl() {
const response = await fetch(this.endpoint);
if (!response.ok) throw new Error('API request failed (' + response.status + ')');
const data = await response.json();
const tracks = (data && Array.isArray(data.results)) ? data.results : [];
const track = tracks.find(item => item && item.previewUrl);
if (!track) throw new Error('No playable preview URL found');
return track.previewUrl;
}
async startMusic() {
const previewUrl = await this.fetchPreviewUrl();
const audio = new Audio(previewUrl);
audio.volume = 0.35;
audio.loop = true;
await audio.play();
}
}
console.log('PeppaMusicApiController loaded');
Part 6: Error Handling Best Practices
Why Error Handling Matters
Networks fail. Servers go down. APIs change. Always handle errors gracefully:
Key patterns:
tryblock: Code that might failcatchblock: Handle the error gracefully- Always log errors for debugging
- Provide fallback behavior (game continues, shows message, etc.)
This is the same architecture your final game runner uses.
Transition to End Product
Run the final game cell at the top. It is the completed version of this lesson pattern integrated into PeppaPigGame.
%%js
async function startMusicSafely(controller) {
try {
const previewUrl = await controller.fetchPreviewUrl();
const audio = new Audio(previewUrl);
audio.volume = 0.35;
audio.loop = true;
await audio.play();
console.log('Music started successfully');
} catch (error) {
console.warn('Failed to play music:', error);
}
}
console.log('startMusicSafely helper loaded');