Really-amin's picture
Upload 577 files
b190b45 verified

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:

  1. On Every Request: Before adding Authorization header
  2. Automatic Removal: Expired tokens are removed from localStorage
  3. 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.