Practice Questions — Fetch API - Getting Data from the Internet
← Back to NotesTopic-Specific Questions
Question 1
Easy
What does
response.ok return when the server responds with status 200?ok is true for status codes 200-299.
trueQuestion 2
Easy
What does
response.ok return when the server responds with status 404?404 means Not Found.
falseQuestion 3
Easy
What is the output?
const obj = { name: "Aarav", age: 16 };
const json = JSON.stringify(obj);
console.log(typeof json);
console.log(json);JSON.stringify converts an object to a JSON string.
string{"name":"Aarav","age":16}Question 4
Easy
What is the output?
const json = '{"name":"Priya","score":95}';
const obj = JSON.parse(json);
console.log(obj.name);
console.log(obj.score + 5);JSON.parse converts a JSON string to a JavaScript object.
Priya100Question 5
Easy
What is the output?
const users = [
{ name: "Aarav", city: "Delhi" },
{ name: "Priya", city: "Mumbai" }
];
users.forEach(function(user) {
console.log(user.name + " from " + user.city);
});forEach iterates through each user object.
Aarav from DelhiPriya from MumbaiQuestion 6
Easy
Why do we need to call
response.json() after fetch()? Why does fetch not give us the JSON directly?The response body can be different formats.
The fetch Response object contains the HTTP response metadata (status, headers) and a body stream. The body could be JSON, text, a blob (image), or other formats.
response.json() reads the body stream and parses it as JSON. response.text() reads it as plain text. You choose the parsing method based on what the API returns.Question 7
Medium
What is the output?
async function test() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
console.log(typeof response);
console.log(response.ok);
console.log(response.status);
}
test();fetch returns a Response object. jsonplaceholder returns 200 for valid IDs.
objecttrue200Question 8
Medium
What is the output?
const data = [
{ id: 1, name: "Post 1" },
{ id: 2, name: "Post 2" },
{ id: 3, name: "Post 3" }
];
const filtered = data.filter(item => item.id > 1);
console.log(filtered.length);
console.log(filtered.map(item => item.name));filter keeps items where id > 1. map extracts names.
2["Post 2", "Post 3"]Question 9
Medium
What is CORS and why does it block some API requests?
Think about security between different websites.
CORS (Cross-Origin Resource Sharing) is a browser security feature that prevents web pages from making requests to a different domain unless the server explicitly allows it. When your page at mysite.com tries to fetch from api.other.com, the browser checks if the API server includes the Access-Control-Allow-Origin header. If not, the request is blocked. CORS prevents malicious websites from making requests to APIs on behalf of unsuspecting users.
Question 10
Hard
What is the output?
async function fetchTwo() {
const [users, posts] = await Promise.all([
fetch("https://jsonplaceholder.typicode.com/users").then(r => r.json()),
fetch("https://jsonplaceholder.typicode.com/posts").then(r => r.json())
]);
console.log("Users:", users.length);
console.log("Posts:", posts.length);
}
fetchTwo();jsonplaceholder has 10 users and 100 posts.
Users: 10Posts: 100Question 11
Hard
Why is it important to check
response.ok before calling response.json()?What happens if the server returns a 404 or 500 error?
If the server returns a 404 or 500, the response body might be an HTML error page, not JSON. Calling
response.json() on HTML will throw a SyntaxError because it is not valid JSON. Also, even if the error response IS JSON (some APIs return JSON error objects), you should handle it differently from success data. Checking response.ok first lets you throw a meaningful error before attempting to parse.Question 12
Medium
What is the output?
const obj = { name: "Aarav", age: 16 };
const json = JSON.stringify(obj);
const parsed = JSON.parse(json);
console.log(parsed.name);
console.log(obj === parsed);JSON.stringify then JSON.parse creates a new object.
AaravfalseQuestion 13
Easy
What is the output?
const data = [1, 2, 3, 4, 5];
const filtered = data.filter(n => n > 3);
console.log(filtered);filter keeps elements where the condition is true.
[4, 5]Mixed & Application Questions
Question 1
Easy
What is the output?
const arr = [10, 20, 30];
const doubled = arr.map(x => x * 2);
console.log(doubled);map creates a new array by applying a function to each element.
[20, 40, 60]Question 2
Easy
What is the output?
const user = { name: "Diya", address: { city: "Pune" } };
console.log(user.address.city);
console.log(user.phone?.number ?? "N/A");Optional chaining and nullish coalescing for missing properties.
PuneN/AQuestion 3
Medium
What is the output?
async function getData() {
return { name: "Aarav" };
}
const result = getData();
console.log(result);
console.log(result.name);async functions always return a Promise.
Promise { { name: 'Aarav' } }undefinedQuestion 4
Medium
What is the output?
const users = [
{ name: "Aarav", active: true },
{ name: "Priya", active: false },
{ name: "Rohan", active: true }
];
const active = users.filter(u => u.active).map(u => u.name);
console.log(active);filter keeps active users, map extracts names.
["Aarav", "Rohan"]Question 5
Medium
What is the output?
try {
const obj = JSON.parse("not json");
} catch (error) {
console.log(error.name);
}
try {
const obj = JSON.parse('{"name": "Aarav"}');
console.log(obj.name);
} catch (error) {
console.log("Error");
}First parse fails (SyntaxError). Second parse succeeds.
SyntaxErrorAaravQuestion 6
Hard
What is the output?
async function fetchUser() {
// Simulating fetch
return { name: "Aarav", scores: [85, 92, 78] };
}
async function main() {
const user = await fetchUser();
const { name, scores } = user;
const avg = scores.reduce((sum, s) => sum + s, 0) / scores.length;
console.log(name + ": " + avg.toFixed(1));
}
main();Destructure the user, then calculate average of scores.
Aarav: 85.0Question 7
Hard
What is the output?
async function fetchWithRetry(url, retries) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error("HTTP " + response.status);
return await response.json();
} catch (error) {
console.log("Attempt " + (i + 1) + " failed: " + error.message);
if (i === retries - 1) throw error;
}
}
}
// Assuming all 3 attempts fail with 404
fetchWithRetry("https://jsonplaceholder.typicode.com/users/9999", 3)
.catch(e => console.log("Final: " + e.message));User 9999 does not exist (404). All 3 attempts will fail.
Attempt 1 failed: HTTP 404Attempt 2 failed: HTTP 404Attempt 3 failed: HTTP 404Final: HTTP 404Question 8
Medium
What is the difference between
response.json() and JSON.parse()?One works with a Response stream, the other with a string.
response.json() reads the Response body stream and parses it as JSON. It returns a Promise because reading the stream is async. JSON.parse() takes a plain string and parses it synchronously. You cannot call JSON.parse on a Response object, and you cannot call .json() on a string.Question 9
Hard
When building a search feature that fetches from an API on every keystroke, what problems can occur and how do you solve them?
Think about too many requests and out-of-order responses.
Two main problems: (1) Too many requests: typing 'Delhi' sends 5 requests (D, De, Del, Delh, Delhi). Solution: debouncing -- wait 300-500ms after the last keystroke before fetching. (2) Out-of-order responses: the request for 'De' might return after the request for 'Delhi', replacing correct results with stale ones. Solution: store the latest search term and ignore responses for outdated queries, or use AbortController to cancel previous requests.
Multiple Choice Questions
MCQ 1
What does the Fetch API return?
Answer: B
B is correct.
B is correct.
fetch() returns a Promise. That Promise resolves to a Response object. You then call response.json() to get the actual data.MCQ 2
Which method parses a fetch Response body as JSON?
Answer: C
C is correct.
C is correct.
response.json() reads the response body and parses it as JSON. It returns a Promise. Option D does not work because Response is not a string.MCQ 3
What does API stand for?
Answer: B
B is correct. API stands for Application Programming Interface. It defines how different software systems communicate with each other.
B is correct. API stands for Application Programming Interface. It defines how different software systems communicate with each other.
MCQ 4
What format do most web APIs return data in?
Answer: C
C is correct. JSON (JavaScript Object Notation) is the standard data format for web APIs. It is lightweight, human-readable, and natively supported by JavaScript.
C is correct. JSON (JavaScript Object Notation) is the standard data format for web APIs. It is lightweight, human-readable, and natively supported by JavaScript.
MCQ 5
What status code means 'success' in HTTP?
Answer: B
B is correct. 200 means 'OK' (success). 100 is informational. 404 is Not Found. 500 is Internal Server Error.
B is correct. 200 means 'OK' (success). 100 is informational. 404 is Not Found. 500 is Internal Server Error.
MCQ 6
Does
fetch() reject its Promise when the server returns a 404 error?Answer: B
B is correct. fetch only rejects on network failures (server unreachable, no internet). HTTP error responses (404, 500) still resolve the Promise. You must check
B is correct. fetch only rejects on network failures (server unreachable, no internet). HTTP error responses (404, 500) still resolve the Promise. You must check
response.ok to detect HTTP errors.MCQ 7
What must you include in the body of a POST request when sending JSON data?
Answer: B
B is correct. The body must be a string.
B is correct. The body must be a string.
JSON.stringify() converts a JavaScript object to a JSON string. Sending the object directly would result in '[object Object]'.MCQ 8
What header tells the server the format of the data you are sending?
Answer: C
C is correct.
C is correct.
Content-Type: application/json tells the server that the request body is JSON. Accept tells the server what format you want in the response.MCQ 9
What is the purpose of a loading state in a fetch-based UI?
Answer: B
B is correct. Loading states (spinners, 'Loading...' text) tell users that something is happening. Without them, users might think the app is frozen or click buttons multiple times.
B is correct. Loading states (spinners, 'Loading...' text) tell users that something is happening. Without them, users might think the app is frozen or click buttons multiple times.
MCQ 10
What is CORS?
Answer: C
C is correct. CORS (Cross-Origin Resource Sharing) prevents web pages from making requests to different domains unless the server explicitly allows it. It protects users from malicious cross-site requests.
C is correct. CORS (Cross-Origin Resource Sharing) prevents web pages from making requests to different domains unless the server explicitly allows it. It protects users from malicious cross-site requests.
MCQ 11
Why should you use
Promise.all when fetching multiple independent API endpoints?Answer: B
B is correct. Promise.all starts all requests simultaneously. Five 200ms requests take ~200ms total with Promise.all, but ~1000ms if awaited sequentially.
B is correct. Promise.all starts all requests simultaneously. Five 200ms requests take ~200ms total with Promise.all, but ~1000ms if awaited sequentially.
MCQ 12
What does
response.status contain?Answer: B
B is correct.
B is correct.
response.status is the numeric HTTP status code. 200 = OK, 201 = Created, 404 = Not Found, 500 = Server Error. response.ok is the boolean (true for 200-299).MCQ 13
What is debouncing in the context of a search feature?
Answer: B
B is correct. Debouncing delays the API call until the user stops typing (e.g., 300ms after the last keystroke). This prevents sending a request for every single character typed.
B is correct. Debouncing delays the API call until the user stops typing (e.g., 300ms after the last keystroke). This prevents sending a request for every single character typed.
MCQ 14
What does
JSON.stringify() do?Answer: B
B is correct.
B is correct.
JSON.stringify converts a JavaScript object or array into a JSON-formatted string. This is needed when sending data in a POST request body.MCQ 15
What HTTP method is used to send new data to a server?
Answer: B
B is correct. POST is used to send data to a server to create a new resource. GET is for retrieving data. FETCH and SEND are not HTTP methods.
B is correct. POST is used to send data to a server to create a new resource. GET is for retrieving data. FETCH and SEND are not HTTP methods.
MCQ 16
What does
response.json() return?Answer: C
C is correct.
C is correct.
response.json() reads the response body stream and parses it as JSON. Because reading the stream is asynchronous, it returns a Promise. You need await response.json().MCQ 17
What status code means 'Not Found'?
Answer: C
C is correct. 404 means the requested resource was not found on the server. 200 is success, 301 is redirect, 500 is server error.
C is correct. 404 means the requested resource was not found on the server. 200 is success, 301 is redirect, 500 is server error.
MCQ 18
What is
response.statusText for a 404 response?Answer: B
B is correct.
B is correct.
response.statusText contains the human-readable status message. For 404, it is 'Not Found'. For 200, it is 'OK'. For 500, it is 'Internal Server Error'.MCQ 19
Why might you get a CORS error when fetching from
localhost to an external API?Answer: B
B is correct. CORS errors occur when the API server does not allow your origin (like http://localhost:3000). The server must include the
B is correct. CORS errors occur when the API server does not allow your origin (like http://localhost:3000). The server must include the
Access-Control-Allow-Origin header to permit cross-origin requests.MCQ 20
What is the default HTTP method when you call
fetch(url) without options?Answer: C
C is correct. By default, fetch makes a GET request. You must explicitly set
C is correct. By default, fetch makes a GET request. You must explicitly set
method: 'POST' in the options to make a POST request.Coding Challenges
Challenge 1: Fetch and Display a User
EasyWrite an async function displayUser(id) that fetches a user from jsonplaceholder.typicode.com/users/{id} and logs their name, email, and city.
Sample Input
displayUser(1)
Sample Output
Name: Leanne Graham
Email: Sincere@april.biz
City: Gwenborough
Use async/await. Handle errors with try-catch.
async function displayUser(id) {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users/' + id);
if (!response.ok) throw new Error('User not found');
const user = await response.json();
console.log('Name:', user.name);
console.log('Email:', user.email);
console.log('City:', user.address.city);
} catch (error) {
console.log('Error:', error.message);
}
}
displayUser(1);Challenge 2: Fetch Multiple Users
EasyWrite an async function getUserNames(ids) that takes an array of user IDs, fetches all users in parallel using Promise.all, and returns an array of their names.
Sample Input
[1, 2, 3]
Sample Output
["Leanne Graham", "Ervin Howell", "Clementine Bauch"]
Use Promise.all for parallel fetching. Return the names array.
async function getUserNames(ids) {
const promises = ids.map(id =>
fetch('https://jsonplaceholder.typicode.com/users/' + id)
.then(r => r.json())
.then(user => user.name)
);
return Promise.all(promises);
}
getUserNames([1, 2, 3]).then(names => console.log(names));Challenge 3: Create a Post via API
MediumWrite an async function createPost(title, body) that sends a POST request to jsonplaceholder.typicode.com/posts with the title, body, and userId: 1. Log the created post's id and title.
Sample Input
createPost('My Post', 'Hello world')
Sample Output
Created post #101: My Post
Use method POST, Content-Type header, and JSON.stringify for the body.
async function createPost(title, body) {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title, body, userId: 1 })
});
if (!response.ok) throw new Error('Failed to create');
const post = await response.json();
console.log('Created post #' + post.id + ': ' + post.title);
} catch (error) {
console.log('Error:', error.message);
}
}
createPost('My Post', 'Hello world');Challenge 4: Safe Fetch Wrapper
MediumWrite an async function safeFetch(url) that wraps fetch with proper error handling. It should return { ok: true, data } on success and { ok: false, error } on failure. Handle both network errors and HTTP errors.
Sample Input
safeFetch('https://jsonplaceholder.typicode.com/users/1')
Sample Output
{ ok: true, data: { id: 1, name: 'Leanne Graham', ... } }
Check response.ok. Use try-catch. Return a consistent object shape.
async function safeFetch(url) {
try {
const response = await fetch(url);
if (!response.ok) {
return { ok: false, error: 'HTTP ' + response.status + ': ' + response.statusText };
}
const data = await response.json();
return { ok: true, data };
} catch (error) {
return { ok: false, error: error.message };
}
}
async function demo() {
const r1 = await safeFetch('https://jsonplaceholder.typicode.com/users/1');
console.log(r1.ok ? r1.data.name : r1.error);
const r2 = await safeFetch('https://jsonplaceholder.typicode.com/users/9999');
console.log(r2.ok ? r2.data.name : r2.error);
}
demo();Challenge 5: User Card Page with Loading and Error States
MediumBuild a complete page that fetches all users from jsonplaceholder.typicode.com/users and displays them as cards. Show 'Loading...' while fetching, user cards on success, and an error message on failure. Use proper error handling.
Sample Input
Page loads automatically
Sample Output
Loading... -> 10 user cards with name, email, and city
Show three states: loading, success, error. Use async/await and DOM manipulation.
// HTML: <div id="app"></div>
async function loadUsers() {
const app = document.getElementById('app');
app.innerHTML = '<p>Loading users...</p>';
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
if (!response.ok) throw new Error('Failed: HTTP ' + response.status);
const users = await response.json();
app.innerHTML = '';
users.forEach(user => {
const card = document.createElement('div');
card.style.cssText = 'background:#16213e;padding:16px;margin:8px;border-radius:8px;';
card.innerHTML = '<h3>' + user.name + '</h3>' +
'<p>Email: ' + user.email + '</p>' +
'<p>City: ' + user.address.city + '</p>';
app.appendChild(card);
});
} catch (error) {
app.innerHTML = '<p style="color:#ef4444;">Error: ' + error.message + '</p>';
}
}
loadUsers();Challenge 6: Search Posts by Keyword
HardFetch all posts from jsonplaceholder.typicode.com/posts. Write a function searchPosts(keyword) that filters posts where the title or body includes the keyword (case-insensitive). Display matching results.
Sample Input
searchPosts('sunt')
Sample Output
Found 5 posts containing 'sunt'
Fetch all posts once, then filter client-side. Use includes() for searching. Case-insensitive.
let allPosts = [];
async function loadPosts() {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
allPosts = await response.json();
console.log('Loaded', allPosts.length, 'posts');
}
function searchPosts(keyword) {
const kw = keyword.toLowerCase();
const results = allPosts.filter(post =>
post.title.toLowerCase().includes(kw) ||
post.body.toLowerCase().includes(kw)
);
console.log('Found ' + results.length + " posts containing '" + keyword + "'");
results.forEach(post => console.log(' - ' + post.title));
return results;
}
async function main() {
await loadPosts();
searchPosts('sunt');
}
main();Challenge 7: User Detail Page with Related Posts
HardFetch a user by ID and their posts in parallel (both from jsonplaceholder). Display the user's name and email, followed by a list of their post titles.
Sample Input
loadUserPage(1)
Sample Output
User: Leanne Graham (Sincere@april.biz)
Posts (10):
- sunt aut facere...
- qui est esse...
Use Promise.all for parallel fetching. Users at /users/{id}, posts at /posts?userId={id}.
async function loadUserPage(userId) {
try {
const [user, posts] = await Promise.all([
fetch('https://jsonplaceholder.typicode.com/users/' + userId).then(r => r.json()),
fetch('https://jsonplaceholder.typicode.com/posts?userId=' + userId).then(r => r.json())
]);
console.log('User:', user.name, '(' + user.email + ')');
console.log('Posts (' + posts.length + '):');
posts.forEach(post => console.log(' - ' + post.title));
} catch (error) {
console.log('Error:', error.message);
}
}
loadUserPage(1);Challenge 8: API Data Cache
HardBuild a cachedFetch(url) function that caches responses. If the same URL is requested again, return the cached data instead of making a new network request. Log whether the data came from cache or network.
Sample Input
cachedFetch('/users/1') twice
Sample Output
First call: [network] fetched /users/1
Second call: [cache] returned /users/1
Use a Map or object as cache. Return cached data if available.
const cache = new Map();
async function cachedFetch(url) {
if (cache.has(url)) {
console.log('[cache] returned', url);
return cache.get(url);
}
const response = await fetch(url);
if (!response.ok) throw new Error('HTTP ' + response.status);
const data = await response.json();
cache.set(url, data);
console.log('[network] fetched', url);
return data;
}
async function demo() {
const user1 = await cachedFetch('https://jsonplaceholder.typicode.com/users/1');
console.log(user1.name);
const user1again = await cachedFetch('https://jsonplaceholder.typicode.com/users/1');
console.log(user1again.name);
console.log('Cache size:', cache.size);
}
demo();Need to Review the Concepts?
Go back to the detailed notes for this chapter.
Read Chapter NotesWant to learn web development with a live mentor?
Explore our Frontend Masterclass