Documentation Index
Fetch the complete documentation index at: https://mintlify.com/diegoromemora27-creator/HTMLCSSEXPLAIN/llms.txt
Use this file to discover all available pages before exploring further.
What is the Fetch API?
Fetch is a built-in browser function for making HTTP requests (GET, POST, PUT, DELETE) to remote servers (APIs).
const response = await fetch(url);
const data = await response.json();
Basic GET Request
const API_URL = "https://api.escuelajs.co/api/v1/products";
async function fetchProducts(limit: number = 20): Promise<Product[]> {
// Build URL with query parameter
const url = `${API_URL}?limit=${limit}`;
console.log(`Fetching: ${url}`);
// Send GET request and wait for response
const response = await fetch(url);
// Check if response was successful (status 200-299)
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
// Parse JSON and type it as Product[]
const data = await response.json() as Product[];
console.log(`Products received: ${data.length}`);
return data;
}
The Fetch Process
Step 1: Send Request
const response = await fetch(url);
Returns a Response object with:
response.status - HTTP status code (200, 404, 500, etc.)
response.ok - true if status is 200-299
response.headers - Response headers
- Methods to get body:
.json(), .text(), .blob()
Step 2: Check Status
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
Step 3: Parse Response Body
// For JSON
const data = await response.json();
// For plain text
const text = await response.text();
// For files/images
const blob = await response.blob();
URL Building with Template Literals
const API_URL = "https://api.escuelajs.co/api/v1/products";
const limit = 20;
// Template literal: embed variables in string
const url = `${API_URL}?limit=${limit}`;
// Result: "https://api.escuelajs.co/api/v1/products?limit=20"
Multiple Query Parameters
const baseUrl = "https://api.example.com/products";
const limit = 20;
const category = "electronics";
const sort = "price";
const url = `${baseUrl}?limit=${limit}&category=${category}&sort=${sort}`;
// Result: "https://api.example.com/products?limit=20&category=electronics&sort=price"
HTTP Status Codes
Success Codes (2xx)
| Code | Meaning |
|---|
| 200 | OK - Request succeeded |
| 201 | Created - Resource created successfully |
| 204 | No Content - Success but no data to return |
Client Error Codes (4xx)
| Code | Meaning |
|---|
| 400 | Bad Request - Invalid data sent |
| 401 | Unauthorized - Need to authenticate |
| 403 | Forbidden - Not allowed to access |
| 404 | Not Found - Resource doesn’t exist |
Server Error Codes (5xx)
| Code | Meaning |
|---|
| 500 | Internal Server Error - Server problem |
| 503 | Service Unavailable - Server down/overloaded |
Checking Status
const response = await fetch(url);
// Check if successful (200-299)
if (response.ok) {
const data = await response.json();
}
// Check specific status
if (response.status === 404) {
console.log("Resource not found");
}
// Get status text
console.log(response.statusText); // "OK", "Not Found", etc.
Error Handling
async function loadProducts(): Promise<void> {
appState.status = LoadingState.Loading;
appState.error = null;
updateUI();
try {
const products = await fetchProducts(20);
appState.status = LoadingState.Success;
appState.products = products;
} catch (error) {
// Handle any errors (network, server, parsing, etc.)
appState.error = error instanceof Error ? error.message : "Unknown error";
appState.status = LoadingState.Error;
console.error("Error loading products:", error);
}
updateUI();
}
Types of Errors
- Network Error - No internet connection
- HTTP Error - Server returned error status (404, 500)
- Parse Error - Response isn’t valid JSON
- Timeout - Request took too long
try {
const response = await fetch(url);
if (!response.ok) {
// HTTP error (4xx, 5xx)
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const data = await response.json();
// Might throw if response isn't valid JSON
} catch (error) {
if (error instanceof TypeError) {
// Network error (no connection)
console.error("Network error:", error);
} else if (error instanceof SyntaxError) {
// JSON parse error
console.error("Invalid JSON:", error);
} else {
// Other errors
console.error("Error:", error);
}
}
POST Requests
Sending data to the server:
async function createProduct(product: Partial<Product>): Promise<Product> {
const response = await fetch(API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(product),
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
return await response.json() as Product;
}
// Usage
const newProduct = await createProduct({
title: "New Product",
price: 99.99,
description: "A great product",
categoryId: 1,
images: ["https://example.com/image.jpg"]
});
PUT Request (Update)
async function updateProduct(id: number, updates: Partial<Product>): Promise<Product> {
const response = await fetch(`${API_URL}/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(updates),
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
return await response.json() as Product;
}
DELETE Request
async function deleteProduct(id: number): Promise<void> {
const response = await fetch(`${API_URL}/${id}`, {
method: 'DELETE',
});
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
}
Send additional information with requests:
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer token123',
'Accept': 'application/json',
},
});
| Header | Purpose |
|---|
Content-Type | Format of data being sent |
Authorization | Authentication credentials |
Accept | Format of data you want back |
User-Agent | Info about your app |
JSON Parsing
response.json()
Parses JSON and returns JavaScript object/array:
const data = await response.json() as Product[];
Type Assertion with ‘as’
// Tell TypeScript what type the data is
const products = await response.json() as Product[];
const user = await response.json() as User;
const config = await response.json() as AppConfig;
Manual JSON Parsing
const text = await response.text();
const data = JSON.parse(text);
Timeout Handling
Fetch doesn’t have built-in timeout. Use AbortController:
async function fetchWithTimeout(url: string, timeout: number = 5000): Promise<Response> {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { signal: controller.signal });
clearTimeout(timeoutId);
return response;
} catch (error) {
clearTimeout(timeoutId);
if (error instanceof Error && error.name === 'AbortError') {
throw new Error('Request timeout');
}
throw error;
}
}
Response Data Validation
Always validate data from external sources:
function isProduct(obj: any): obj is Product {
return (
typeof obj === 'object' &&
typeof obj.id === 'number' &&
typeof obj.title === 'string' &&
typeof obj.price === 'number'
);
}
async function fetchProducts(): Promise<Product[]> {
const response = await fetch(API_URL);
const data = await response.json();
if (!Array.isArray(data)) {
throw new Error('Invalid response: expected array');
}
// Validate each product
data.forEach((item, index) => {
if (!isProduct(item)) {
throw new Error(`Invalid product at index ${index}`);
}
});
return data as Product[];
}
Loading States with Fetch
Combine fetch with state management:
enum LoadingState {
Idle = "IDLE",
Loading = "LOADING",
Success = "SUCCESS",
Error = "ERROR"
}
let appState: AppState = {
status: LoadingState.Idle,
products: [],
error: null
};
async function loadProducts(): Promise<void> {
// Start loading
appState.status = LoadingState.Loading;
appState.error = null;
updateUI();
try {
// Fetch data
const products = await fetchProducts(20);
// Success
appState.status = LoadingState.Success;
appState.products = products;
} catch (error) {
// Error
appState.error = error instanceof Error ? error.message : "Unknown error";
appState.status = LoadingState.Error;
}
// Update UI regardless of outcome
updateUI();
}
CORS (Cross-Origin Resource Sharing)
If fetching from a different domain, the server must allow CORS:
// This might fail with CORS error if server doesn't allow it
const response = await fetch('https://different-domain.com/api');
Error message: Access to fetch at '...' has been blocked by CORS policy
Solution: The API server must include CORS headers. You can’t fix this from the client.
Best Practices
1. Always Check response.ok
if (!response.ok) {
throw new Error(`HTTP Error: ${response.status}`);
}
2. Use Try/Catch
try {
const data = await fetch(url);
} catch (error) {
console.error('Failed:', error);
}
3. Type Your Responses
const data = await response.json() as Product[];
4. Provide User Feedback
// Show loading state
updateUI();
// Fetch data
await fetchData();
// Show success/error
updateUI();
5. Log for Debugging
console.log(`Fetching: ${url}`);
console.log(`Products received: ${data.length}`);
console.error("Error loading products:", error);
Next Steps