Module Recap
Module 05 introduced Promises and the Fetch API — the tools that connect BudgetBuddy to live data from the internet.
What you learned
Section titled “What you learned”Promises represent eventual results. Three states: pending → fulfilled or rejected. Once settled, the state never changes.
.then(fn) runs when the Promise fulfills. Returns a new Promise — chains transform values step by step.
.catch(fn) runs when the Promise rejects, or when any .then callback throws. Handles all errors in the chain.
.finally(fn) runs after the Promise settles, regardless of outcome. Use for cleanup like hiding spinners.
fetch(url) returns a Promise that resolves with a Response object. Only rejects on network failure — check response.ok for HTTP errors.
response.json() parses the body as JSON and returns a Promise. Chain it after the ok check.
Error handling requires covering four failure modes: network failure, HTTP error, malformed JSON, and API-level errors. Each needs explicit handling.
The fetchRates function BudgetBuddy uses
Section titled “The fetchRates function BudgetBuddy uses”const BASE_URL = 'https://open.er-api.com/v6/latest';
let cachedRates = null;
export function fetchRates(baseCurrency = 'USD') { if (cachedRates) return Promise.resolve(cachedRates);
return fetch(`${BASE_URL}/${baseCurrency}`) .then(response => { if (!response.ok) throw new Error(`API error ${response.status}`); return response.json(); }) .then(data => { if (data.result !== 'success') throw new Error(`API error: ${data['error-type']}`); cachedRates = data.rates; return cachedRates; });}This is the complete api.js module — one function, exported as a named export, with caching, HTTP error handling, and API-level error handling.
What is next
Section titled “What is next”Module 06 introduces async/await — a cleaner syntax for writing exactly this kind of asynchronous code. You will rewrite fetchRates and the rest of BudgetBuddy’s async logic in a style that reads like synchronous code, then understand why both syntaxes matter.