JavaScript Fetch API
JavaScript Fetch API Interview with follow-up questions
1. What is the Fetch API in JavaScript?
The Fetch API is the modern, promise-based interface for making HTTP requests. It replaces the older callback-driven XMLHttpRequest and is native in all modern browsers and Node 18+.
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
fetch(url, options) returns a promise that resolves to a Response object; you then read the body with .json(), .text(), .blob(), etc. (each returns a promise).
The #1 gotcha interviewers ask about: fetch only rejects on network failure (DNS, offline, CORS). A 404 or 500 still resolves — so you must check response.ok (or response.status) yourself; it won't throw automatically like some HTTP libraries.
Other points worth raising: configure method/headers/body via the options object, use an AbortController (or AbortSignal.timeout(ms)) to cancel/time out a request, and remember CORS governs cross-origin calls.
Follow-up 1
How does it differ from AJAX?
The Fetch API is a newer and more modern alternative to AJAX (Asynchronous JavaScript and XML). While AJAX uses the XMLHttpRequest object to make HTTP requests, the Fetch API uses the fetch() function. The Fetch API provides a simpler and more intuitive syntax, supports promises for handling asynchronous operations, and allows for more control over the request and response.
Follow-up 2
Can you explain how to use it with an example?
Sure! Here's an example of how to use the Fetch API to make a GET request to an API and handle the response:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
// Handle the data
console.log(data);
})
.catch(error => {
// Handle any errors
console.error(error);
});
Follow-up 3
What are the advantages of using Fetch API over XMLHttpRequest?
There are several advantages of using the Fetch API over XMLHttpRequest:
- Simpler and more intuitive syntax: The Fetch API provides a more modern and cleaner syntax for making HTTP requests.
- Promises-based: The Fetch API uses promises, which makes it easier to handle asynchronous operations and avoid callback hell.
- Better control over requests and responses: The Fetch API allows for more control over the request and response, such as setting headers, handling different types of data, and handling errors.
- Built-in support for JSON: The Fetch API automatically parses JSON responses, making it easier to work with JSON data.
- Better browser support: The Fetch API is supported by all modern browsers, while XMLHttpRequest has some limitations in older browsers.
Follow-up 4
How do you handle errors in Fetch API?
To handle errors in the Fetch API, you can use the catch() method on the promise returned by the fetch() function. Here's an example:
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
// Handle the data
console.log(data);
})
.catch(error => {
// Handle the error
console.error(error);
});
2. How can you make a POST request using the Fetch API?
Pass an options object with method: 'POST', a serialized body, and the matching Content-Type header. Using async/await:
async function createUser(data) {
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
return response.json();
}
Things interviewers check for:
- Set
Content-Typeto match the body. For JSON,application/json; for file uploads useFormData(and omitContent-Type— the browser sets the multipart boundary for you). - Check
response.ok—fetchwon't reject on a 4xx/5xx, only on network errors. - Send cookies with
credentials: 'include'when the API needs auth cookies cross-origin. - Pass
signal: AbortSignal.timeout(5000)to bound the request time.
Follow-up 1
What should be included in the headers of a POST request?
In the headers of a POST request, you should include the 'Content-Type' header to specify the format of the data being sent in the request body. For example, if you are sending JSON data, you should include the 'Content-Type' header with the value 'application/json'. Here's an example:
fetch('https://api.example.com/endpoint', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
// Handle the response data
})
.catch(error => {
// Handle any errors
});
Follow-up 2
How do you send JSON data in the body of a POST request?
To send JSON data in the body of a POST request, you need to convert the data to a JSON string using JSON.stringify() and set it as the value of the body option in the request. Here's an example:
const data = {
name: 'John Doe',
age: 30
};
fetch('https://api.example.com/endpoint', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
// Handle the response data
})
.catch(error => {
// Handle any errors
});
Follow-up 3
How do you handle the response of a POST request?
To handle the response of a POST request, you can use the then() method on the response object returned by the fetch() function. You can chain multiple then() methods to handle the response data in different ways. For example, you can use the json() method to parse the response data as JSON. Here's an example:
fetch('https://api.example.com/endpoint', {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
// Handle the response data
})
.catch(error => {
// Handle any errors
});
3. What is the purpose of the 'options' object in a fetch request?
The options object (the second argument to fetch) configures the request beyond the default GET. The properties you should be able to name:
fetch(url, {
method: 'POST', // GET, POST, PUT, PATCH, DELETE…
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data), // request payload (not for GET/HEAD)
credentials: 'include', // send cookies (omit | same-origin | include)
signal: AbortSignal.timeout(5000), // cancel / timeout via AbortController
mode: 'cors', // cors | same-origin | no-cors
cache: 'no-store', // caching behavior
});
The ones interviewers most often probe:
bodymust be a string/FormData/Blob/etc.; serialize objects withJSON.stringifyand set a matchingContent-Type. WithFormData, don't setContent-Type— the browser adds the boundary.credentialscontrols whether cookies ride along — needed for cookie-based auth on cross-origin calls.signalwires in anAbortControllerso you can cancel or time out the request — the modern alternative to leaving requests hanging.
Follow-up 1
What are some common properties you can include in the 'options' object?
Some common properties that can be included in the 'options' object are:
- 'method': Specifies the request method (e.g., GET, POST, PUT, DELETE).
- 'headers': Specifies the headers to be included in the request.
- 'body': Specifies the body content of the request.
- 'mode': Specifies the mode of the request (e.g., 'cors', 'no-cors', 'same-origin').
- 'cache': Specifies the cache mode of the request (e.g., 'default', 'no-store', 'reload', 'no-cache').
- 'credentials': Specifies whether to include cookies in the request (e.g., 'same-origin', 'include', 'omit').
- 'redirect': Specifies how redirects are handled (e.g., 'follow', 'error', 'manual').
- 'referrer': Specifies the referrer of the request (e.g., 'no-referrer', 'client').
Follow-up 2
How do you specify the request method in the 'options' object?
To specify the request method in the 'options' object, you can use the 'method' property. For example:
fetch(url, {
method: 'POST'
})
Follow-up 3
How do you include headers in the 'options' object?
To include headers in the 'options' object, you can use the 'headers' property. The 'headers' property should be an object where each key-value pair represents a header name and its value. For example:
fetch(url, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token'
}
})
4. How do you handle responses that are not a 200 OK status?
This is the classic fetch gotcha: fetch does not reject on HTTP error statuses. A 404 or 500 still resolves successfully — the promise only rejects on a network-level failure. So you must inspect the Response yourself, typically via response.ok (true for any 2xx status):
const response = await fetch('/api/data');
if (!response.ok) {
// 4xx or 5xx — fetch did NOT throw on its own
throw new Error(`HTTP ${response.status} ${response.statusText}`);
}
const data = await response.json();
Patterns interviewers like to see:
- Centralize the check in a wrapper so every call handles it consistently.
- Read the error body for API messages — e.g.
const err = await response.json()before throwing. - Branch on
response.statuswhen you need to react differently (401 → redirect to login, 429 → back off and retry). - Combine with
try/catchso you handle both network rejections and HTTP-error throws in one place.
Follow-up 1
What does the 'ok' property of a Response object indicate?
The 'ok' property of a Response object indicates whether the response was successful or not. If the 'ok' property is true, it means the response was successful (status code 200). If the 'ok' property is false, it means the response was not successful (status code other than 200). You can use this property to check the status of the response and handle it accordingly.
Follow-up 2
How do you access the status code of a response?
To access the status code of a response, you can use the 'status' property of the Response object. The 'status' property returns the HTTP status code of the response. For example, if the response is a 200 OK status, the 'status' property will return 200. You can use this property to check the status code and handle the response accordingly.
Follow-up 3
What is a common way to handle 404 Not Found responses?
A common way to handle 404 Not Found responses is to check the status code of the response. If the status code is 404, it means the requested resource was not found. You can then display an appropriate error message to the user or take some other action based on your application's requirements. For example, you might show a 'Page Not Found' message or redirect the user to a different page.
5. Can you explain how to use the Fetch API to make a request to a third-party API?
Call fetch() with the third-party URL and handle the Response. Using async/await with proper error and status handling:
async function getData() {
try {
const response = await fetch('https://api.example.com/data', {
headers: { Authorization: `Bearer ${token}` },
signal: AbortSignal.timeout(5000),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (err) {
console.error('Fetch failed:', err);
throw err;
}
}
What makes a third-party request different — and what interviewers want you to mention:
- CORS: the browser blocks cross-origin responses unless the third-party server sends the right
Access-Control-Allow-Originheaders. You can't fix CORS from the client; the server (or a proxy) must allow it. - Auth: API keys/tokens usually go in headers (
Authorization), not the URL. Avoid exposing secret keys in client-side code — proxy through your backend instead. - Still check
response.ok(a 404/500 won't reject) and bound the call withAbortSignal.timeout.
Follow-up 1
How do you include an API key in your request?
To include an API key in your request, you can add it as a query parameter or include it in the request headers. Here's an example of how to include an API key as a query parameter:
fetch('https://api.example.com/data?api_key=YOUR_API_KEY')
.then(response => response.json())
.then(data => {
// Do something with the data
})
.catch(error => {
// Handle any errors
});
In this example, we add the api_key parameter to the URL with the value of your API key. Alternatively, you can include the API key in the request headers using the Headers object:
const headers = new Headers();
headers.append('Authorization', 'Bearer YOUR_API_KEY');
fetch('https://api.example.com/data', {
headers: headers
})
.then(response => response.json())
.then(data => {
// Do something with the data
})
.catch(error => {
// Handle any errors
});
Follow-up 2
How do you handle CORS issues?
To handle CORS (Cross-Origin Resource Sharing) issues when making a request to a third-party API, you can set the appropriate headers in your request. Here's an example of how to handle CORS issues using the Fetch API:
fetch('https://api.example.com/data', {
mode: 'cors'
})
.then(response => response.json())
.then(data => {
// Do something with the data
})
.catch(error => {
// Handle any errors
});
In this example, we set the mode option to 'cors' in the request options. This tells the browser to include the necessary CORS headers in the request. If the server allows cross-origin requests, the request will be successful. If the server does not allow cross-origin requests, you may need to handle the error or use a proxy server.
Follow-up 3
How do you parse the JSON response from the API?
To parse the JSON response from the API, you can use the .json() method on the response object. Here's an example:
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => {
// Do something with the data
})
.catch(error => {
// Handle any errors
});
In this example, we use the .json() method to parse the response as JSON. The resulting data can then be accessed and used in the second .then() callback. If the response is not valid JSON, an error will be thrown and can be caught in the .catch() callback.
Live mock interview
Mock interview: JavaScript Fetch API
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.