API Helper Utilities
Overview
The APIHelper class provides a comprehensive set of utilities for making API requests, handling authentication, and managing common operations across the application.
Features
- β Token Management: Automatic JWT expiration checking
- β API Requests: Simplified fetch with error handling
- β Data Extraction: Smart array extraction from various response formats
- β Health Monitoring: Periodic API health checks
- β UI Helpers: Toast notifications, formatting utilities
- β Performance: Debounce and throttle functions
Usage
Basic Import
import { APIHelper } from '../../shared/js/utils/api-helper.js';
API Methods
Authentication
getHeaders()
Returns headers with optional Authorization token. Automatically checks token expiration.
const headers = APIHelper.getHeaders();
// Returns: { 'Content-Type': 'application/json', 'Authorization': 'Bearer <token>' }
isTokenExpired(token)
Checks if a JWT token is expired.
const expired = APIHelper.isTokenExpired(token);
// Returns: boolean
API Requests
fetchAPI(url, options)
Fetch data with automatic authorization and error handling.
// GET request
const data = await APIHelper.fetchAPI('/api/market/top?limit=10');
// POST request
const result = await APIHelper.fetchAPI('/api/sentiment/analyze', {
method: 'POST',
body: JSON.stringify({ text: 'Bitcoin is great!' })
});
Data Processing
extractArray(data, keys)
Intelligently extract arrays from various response formats.
// Works with direct arrays
const arr1 = APIHelper.extractArray([1, 2, 3]);
// Works with nested data
const arr2 = APIHelper.extractArray({ markets: [...] }, ['markets', 'data']);
// Works with objects
const arr3 = APIHelper.extractArray({ item1: {}, item2: {} });
Health Monitoring
checkHealth()
Check API health status.
const health = await APIHelper.checkHealth();
// Returns: { status: 'online', healthy: true, data: {...} }
monitorHealth(callback, interval)
Setup periodic health monitoring.
const intervalId = APIHelper.monitorHealth((health) => {
console.log('API Status:', health.status);
if (!health.healthy) {
console.warn('API is down!');
}
}, 30000); // Check every 30 seconds
// Later, stop monitoring
clearInterval(intervalId);
UI Utilities
showToast(message, type, duration)
Display toast notifications.
APIHelper.showToast('Operation successful!', 'success');
APIHelper.showToast('Something went wrong', 'error');
APIHelper.showToast('Please wait...', 'info');
APIHelper.showToast('Check your input', 'warning');
formatCurrency(amount, currency)
Format numbers as currency.
const formatted = APIHelper.formatCurrency(1234.56);
// Returns: "$1,234.56"
formatPercentage(value, decimals)
Format values as percentages.
const percent = APIHelper.formatPercentage(2.5);
// Returns: "+2.50%"
formatNumber(num, options)
Format numbers with locale settings.
const formatted = APIHelper.formatNumber(1000000);
// Returns: "1,000,000"
Performance Utilities
debounce(func, wait)
Debounce function calls.
const debouncedSearch = APIHelper.debounce((query) => {
console.log('Searching:', query);
}, 300);
// Call multiple times, only executes once after 300ms
debouncedSearch('bitcoin');
debouncedSearch('ethereum');
debouncedSearch('solana');
throttle(func, limit)
Throttle function calls.
const throttledScroll = APIHelper.throttle(() => {
console.log('Scroll event');
}, 100);
window.addEventListener('scroll', throttledScroll);
Complete Example: Building a Page
import { APIHelper } from '../../shared/js/utils/api-helper.js';
class YourPage {
constructor() {
this.data = [];
this.healthMonitor = null;
}
async init() {
// Setup health monitoring
this.healthMonitor = APIHelper.monitorHealth((health) => {
console.log('API Health:', health.status);
});
// Load data
await this.loadData();
// Setup event listeners
this.bindEvents();
}
async loadData() {
try {
// Fetch data using APIHelper
const response = await APIHelper.fetchAPI('/api/your-endpoint');
// Extract array safely
this.data = APIHelper.extractArray(response, ['data', 'items']);
// Render
this.render();
// Show success
APIHelper.showToast('Data loaded successfully!', 'success');
} catch (error) {
console.error('Load error:', error);
// Use fallback data
this.data = this.getDemoData();
this.render();
// Show error
APIHelper.showToast('Using demo data', 'warning');
}
}
bindEvents() {
// Debounced search
const searchInput = document.getElementById('search');
const debouncedSearch = APIHelper.debounce((query) => {
this.filterData(query);
}, 300);
searchInput?.addEventListener('input', (e) => {
debouncedSearch(e.target.value);
});
}
render() {
// Render your data
this.data.forEach(item => {
const price = APIHelper.formatCurrency(item.price);
const change = APIHelper.formatPercentage(item.change);
console.log(`${item.name}: ${price} (${change})`);
});
}
getDemoData() {
return [
{ name: 'Bitcoin', price: 50000, change: 2.5 },
{ name: 'Ethereum', price: 3000, change: -1.2 }
];
}
destroy() {
// Cleanup
if (this.healthMonitor) {
clearInterval(this.healthMonitor);
}
}
}
// Initialize
const page = new YourPage();
page.init();
Best Practices
1. Always Use APIHelper for Fetch Requests
// β
Good
const data = await APIHelper.fetchAPI('/api/endpoint');
// β Avoid
const response = await fetch('/api/endpoint');
const data = await response.json();
2. Extract Arrays Safely
// β
Good
const items = APIHelper.extractArray(response, ['items', 'data']);
// β Avoid (can fail)
const items = response.items;
3. Use Debounce for User Input
// β
Good
const debouncedHandler = APIHelper.debounce(handler, 300);
input.addEventListener('input', debouncedHandler);
// β Avoid (too many calls)
input.addEventListener('input', handler);
4. Monitor API Health
// β
Good
APIHelper.monitorHealth((health) => {
updateUI(health.status);
});
// β Avoid (no health awareness)
// Just hope the API is up
Token Expiration
The APIHelper automatically checks JWT token expiration:
- On Every Request: Before adding Authorization header
- Automatic Removal: Expired tokens are removed from localStorage
- Graceful Degradation: Requests continue without auth if token expired
// Token is checked automatically
const data = await APIHelper.fetchAPI('/api/protected-route');
// If token expired, it's removed and request proceeds without auth
Error Handling
All APIHelper methods handle errors gracefully:
try {
const data = await APIHelper.fetchAPI('/api/endpoint');
// Use data
} catch (error) {
// Error is already logged by APIHelper
// Use fallback data
const data = getDemoData();
}
Browser Compatibility
- β Modern browsers (ES6+ modules)
- β Chrome 61+
- β Firefox 60+
- β Safari 11+
- β Edge 16+
License
Part of Crypto Monitor ULTIMATE project.