Handling JSON Responses
Most public APIs respond with JSON. Once you have parsed the response with response.json(), you have a regular JavaScript value — but you still need to navigate the response shape to find what you need, and handle cases where the shape is not what you expected.
Parsing and destructuring in one step
Section titled “Parsing and destructuring in one step”You have a JavaScript object after response.json() resolves. Use destructuring immediately to pull out exactly what you need:
fetch('https://open.er-api.com/v6/latest/USD') .then(response => { if (!response.ok) throw new Error(`API error ${response.status}`); return response.json(); }) .then(({ rates, base_code, time_last_update_utc }) => { console.log(`Base: ${base_code}`); console.log(`Updated: ${time_last_update_utc}`); console.log(`EUR: ${rates.EUR}`); console.log(`GBP: ${rates.GBP}`); });Destructuring in the .then callback parameter is idiomatic — you name only what you need and the rest of the response is ignored.
Converting an amount to another currency
Section titled “Converting an amount to another currency”With a rates object, converting is simple multiplication:
function convertAmount(amount, fromCurrency, toCurrency, rates) { if (fromCurrency === toCurrency) return amount; const inUSD = amount / rates[fromCurrency]; return inUSD * rates[toCurrency];}
// If rates are relative to USD:convertAmount(10, 'USD', 'EUR', rates); // 10 * 0.9183 = 9.183convertAmount(10, 'GBP', 'EUR', rates); // (10 / 0.7897) * 0.9183 ≈ 11.63Safe property access
Section titled “Safe property access”If the rates object does not contain a currency code you request, the result is undefined. Multiply with undefined and you get NaN. Guard against this:
function convertAmount(amount, fromCurrency, toCurrency, rates) { const fromRate = rates[fromCurrency]; const toRate = rates[toCurrency]; if (!fromRate || !toRate) throw new Error(`Unknown currency: ${fromCurrency} or ${toCurrency}`); return (amount / fromRate) * toRate;}Checking the result field
Section titled “Checking the result field”The ExchangeRate-API includes a result field. When the request succeeds it is 'success'; on failure it is 'error' with an error-type field. You can check this for more specific error handling:
fetch('https://open.er-api.com/v6/latest/USD') .then(response => { if (!response.ok) throw new Error(`HTTP ${response.status}`); return response.json(); }) .then(data => { if (data.result !== 'success') { throw new Error(`API error: ${data['error-type'] ?? 'unknown'}`); } return data.rates; }) .then(rates => { // safe to use rates here }) .catch(error => console.error(error.message));Parsing errors
Section titled “Parsing errors”If the server returns a response that is not valid JSON, response.json() rejects. The .catch handler will receive that error. Nothing special needed — the chain handles it.
Transforming the response for your app
Section titled “Transforming the response for your app”It is good practice to transform the raw API response into the shape your app actually needs before passing it to other parts of the code. Create a parseRates function that extracts only the currencies BudgetBuddy displays:
const SUPPORTED_CURRENCIES = ['USD', 'EUR', 'GBP', 'CAD', 'JPY', 'AUD'];
function parseRates(data) { const { rates } = data; return SUPPORTED_CURRENCIES.reduce((acc, code) => { if (rates[code] !== undefined) acc[code] = rates[code]; return acc; }, {});}
fetch('https://open.er-api.com/v6/latest/USD') .then(response => { if (!response.ok) throw new Error(`HTTP ${response.status}`); return response.json(); }) .then(parseRates) .then(rates => console.log(rates)); // { USD: 1, EUR: 0.9183, GBP: 0.7897, CAD: 1.3421, JPY: 145.23, AUD: 1.5310 }parseRates is passed directly as the .then callback — it receives the parsed JSON object and returns only the currencies you need.
Exercise
Section titled “Exercise”- Fetch
https://open.er-api.com/v6/latest/USDand destructurerates,base_code, andtime_last_update_utcfrom the parsed JSON. - Write
convertAmount(amount, from, to, rates)with properundefinedguards. Test converting$100 USD → EURand£50 GBP → USD. - Write
parseRates(data)that returns onlyUSD,EUR,GBP,CAD, andJPY. - Chain
parseRatesdirectly as a.thencallback.
- Destructure the parsed JSON in the
.thencallback to extract only what you need. - Currency conversion is
(amount / fromRate) * toRatewhen rates are relative to USD. - Always guard against missing currency codes — undefined rates produce NaN.
- Check
data.result === 'success'for API-level errors distinct from HTTP errors. - Transform raw API responses into your app’s data shape as early as possible in the chain.