19. Advanced JSON and API Manipulation
Why Advanced API Skills Matter
Fetching data is just the start. Real-world apps need to filter, transform, aggregate, and combine API responses dynamically. This lesson covers advanced techniques for handling JSON and APIs in JavaScript.
Parsing and Transforming JSON
Once you fetch JSON, you can manipulate it using array methods, object destructuring, and dynamic access.
const data = {
users: [
{ name: 'Alice', age: 25, location: { city: 'NY' } },
{ name: 'Bob', age: 30, location: { city: 'LA' } }
]
};
// Extract names
const names = data.users.map(u => u.name);
console.log(names); // ['Alice', 'Bob']
// Destructure nested objects
const cities = data.users.map(({ location: { city } }) => city);
console.log(cities); // ['NY', 'LA']Filtering and Reducing Data
You can filter arrays based on conditions and reduce them into summaries or computed results.
const adults = data.users.filter(u => u.age >= 30);
console.log(adults);
const totalAge = data.users.reduce((sum, u) => sum + u.age, 0);
console.log(totalAge); // 55Chaining Fetch Calls
Sometimes one API call depends on the result of another. Chaining allows sequential fetching.
async function fetchPostsAndUsers() {
try {
const postsRes = await fetch('https://jsonplaceholder.typicode.com/posts');
const posts = await postsRes.json();
// Fetch user for the first post
const userId = posts[0].userId;
const userRes = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
const user = await userRes.json();
console.log(`First post by: ${user.name}`);
} catch (err) {
console.error('Error fetching data:', err);
}
}
fetchPostsAndUsers();Merging and Enriching Data
You can combine data from multiple sources, enriching it for your app’s needs.
async function mergeData() {
const [usersRes, postsRes] = await Promise.all([
fetch('https://jsonplaceholder.typicode.com/users'),
fetch('https://jsonplaceholder.typicode.com/posts')
]);
const users = await usersRes.json();
const posts = await postsRes.json();
// Attach user name to each post
const enrichedPosts = posts.map(post => {
const user = users.find(u => u.id === post.userId);
return { ...post, userName: user.name };
});
console.log(enrichedPosts.slice(0, 3)); // Preview first 3 posts
}
mergeData();Error Handling and Validation
Always validate API data. Check for missing fields, unexpected formats, or empty arrays before processing.
async function safeFetch(url) {
try {
const res = await fetch(url);
if (!res.ok) throw new Error('Network error');
const data = await res.json();
if (!data || !Array.isArray(data)) throw new Error('Invalid data format');
return data;
} catch (err) {
console.error('Fetch failed:', err.message);
return [];
}
}Mini Challenge
1. Fetch 10 random users and filter only those aged 25 or older. 2. For each user, fetch a separate endpoint for posts and attach the post count to the user. 3. Display the users sorted by post count descending. 4. Ensure all fetch calls handle errors and invalid data gracefully.