or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

ajax.mdcore-selection.mdcss-styling.mddeferred-promises.mdeffects.mdevents.mdindex.mdmanipulation.mdutilities.md
tile.json

ajax.mddocs/

AJAX Operations

jQuery provides a comprehensive AJAX API for making asynchronous HTTP requests with full TypeScript support. The system includes Promise-like objects, detailed configuration options, and type-safe request/response handling.

AJAX Method Signatures

Core AJAX Interface

interface JQueryStatic {
    // Main AJAX method
    ajax(url: string): JQuery.jqXHR;
    ajax(url: string, settings: JQuery.AjaxSettings): JQuery.jqXHR;
    ajax(settings: JQuery.AjaxSettings): JQuery.jqXHR;
    
    // Convenience methods
    get(url: string): JQuery.jqXHR;
    get(url: string, data: JQuery.PlainObject | string): JQuery.jqXHR;
    get(url: string, data: JQuery.PlainObject | string, success: JQuery.Ajax.SuccessCallback, dataType?: string): JQuery.jqXHR;
    get(url: string, success: JQuery.Ajax.SuccessCallback, dataType?: string): JQuery.jqXHR;
    
    post(url: string): JQuery.jqXHR;
    post(url: string, data: JQuery.PlainObject | string): JQuery.jqXHR;
    post(url: string, data: JQuery.PlainObject | string, success: JQuery.Ajax.SuccessCallback, dataType?: string): JQuery.jqXHR;
    post(url: string, success: JQuery.Ajax.SuccessCallback, dataType?: string): JQuery.jqXHR;
    
    // Specialized methods
    getJSON(url: string): JQuery.jqXHR;
    getJSON(url: string, data: JQuery.PlainObject | string): JQuery.jqXHR;
    getJSON(url: string, data: JQuery.PlainObject | string, success: JQuery.Ajax.SuccessCallback): JQuery.jqXHR;
    getJSON(url: string, success: JQuery.Ajax.SuccessCallback): JQuery.jqXHR;
    
    getScript(url: string): JQuery.jqXHR;
    getScript(url: string, success: JQuery.Ajax.SuccessCallback): JQuery.jqXHR;
    
    // Form loading
    load(url: string): JQuery.jqXHR;
    load(url: string, data: JQuery.PlainObject | string): JQuery.jqXHR;
    load(url: string, data: JQuery.PlainObject | string, complete: JQuery.Ajax.CompleteCallback): JQuery.jqXHR;
    load(url: string, complete: JQuery.Ajax.CompleteCallback): JQuery.jqXHR;
}

AJAX Configuration Types

Settings Interface

declare namespace JQuery.Ajax {
    // Main settings interface
    interface AjaxSettings<TContext = any> {
        // Request configuration
        url?: string;
        type?: string;
        method?: string;
        data?: any;
        contentType?: string | boolean;
        dataType?: string;
        headers?: JQuery.PlainObject<string>;
        
        // Authentication and cross-origin
        username?: string;
        password?: string;
        crossDomain?: boolean;
        xhrFields?: JQuery.PlainObject;
        
        // Timing and behavior
        timeout?: number;
        cache?: boolean;
        async?: boolean;
        processData?: boolean;
        
        // Callbacks
        beforeSend?: (this: TContext, jqXHR: JQuery.jqXHR, settings: AjaxSettings<TContext>) => false | void;
        success?: SuccessCallback<TContext>;
        error?: ErrorCallback<TContext>;
        complete?: CompleteCallback<TContext>;
        dataFilter?: (data: string, type: string) => any;
        
        // Upload progress (if supported)
        xhr?: () => XMLHttpRequest;
        
        // Context for callbacks
        context?: TContext;
        
        // JSONP settings
        jsonp?: string | boolean;
        jsonpCallback?: string | (() => string);
        
        // Status codes
        statusCode?: {
            [key: number]: () => void;
        };
        
        // Converters
        converters?: {
            [key: string]: (value: any) => any;
        };
        
        // Script and style settings
        scriptCharset?: string;
        scriptAttrs?: JQuery.PlainObject<string>;
    }
    
    // Callback types
    type SuccessCallback<TContext = any> = (this: TContext, data: any, textStatus: TextStatus, jqXHR: JQuery.jqXHR) => void;
    type ErrorCallback<TContext = any> = (this: TContext, jqXHR: JQuery.jqXHR, textStatus: TextStatus, errorThrown: string) => void;
    type CompleteCallback<TContext = any> = (this: TContext, jqXHR: JQuery.jqXHR, textStatus: TextStatus) => void;
    
    // Status types
    type TextStatus = "success" | "notmodified" | "nocontent" | "error" | "timeout" | "abort" | "parsererror";
}

jqXHR Object

declare namespace JQuery {
    // Enhanced XMLHttpRequest object
    interface jqXHR extends XMLHttpRequest, Promise<any> {
        // Response properties
        responseJSON?: any;
        responseText: string;
        responseXML?: Document;
        
        // Request information
        readyState: number;
        status: number;
        statusText: string;
        
        // Promise methods
        done(doneCallback: (data: any, textStatus: string, jqXHR: jqXHR) => void): jqXHR;
        fail(failCallback: (jqXHR: jqXHR, textStatus: string, errorThrown: string) => void): jqXHR;
        always(alwaysCallback: (dataOrjqXHR: any, textStatus: string, jqXHROrErrorThrown: jqXHR | string) => void): jqXHR;
        then<TResolve = any, TReject = never>(
            doneFilter?: (data: any, textStatus: string, jqXHR: jqXHR) => TResolve | PromiseLike<TResolve>,
            failFilter?: (jqXHR: jqXHR, textStatus: string, errorThrown: string) => TReject | PromiseLike<TReject>
        ): Promise<TResolve | TReject>;
        
        // Control methods
        abort(statusText?: string): jqXHR;
        
        // Header methods
        getAllResponseHeaders(): string;
        getResponseHeader(name: string): string | null;
        setRequestHeader(name: string, value: string): jqXHR;
        overrideMimeType(type: string): jqXHR;
        
        // State methods
        state(): string;
        statusCode(map: { [key: number]: () => void }): jqXHR;
    }
}

Basic AJAX Requests

GET Requests

// Simple GET request
$.get('/api/users')
    .done(data => console.log('Users:', data))
    .fail((xhr, status, error) => console.error('Error:', error));

// GET with data parameters
$.get('/api/users', { page: 1, limit: 10 })
    .done(users => console.log('Page 1:', users));

// GET with success callback (legacy style)
$.get('/api/users', data => {
    console.log('Users loaded:', data);
}, 'json');

// Type-safe GET request
interface User {
    id: number;
    name: string;
    email: string;
}

$.get('/api/users').done((users: User[]) => {
    users.forEach(user => {
        console.log(`User: ${user.name} (${user.email})`);
    });
});

POST Requests

// Simple POST request
const userData = { name: 'John Doe', email: 'john@example.com' };

$.post('/api/users', userData)
    .done(response => console.log('User created:', response))
    .fail(xhr => console.error('Creation failed:', xhr.responseText));

// POST with JSON data
const postData = JSON.stringify(userData);

$.post('/api/users', postData, 'json')
    .done(response => console.log('Response:', response));

// Type-safe POST request
interface CreateUserRequest {
    name: string;
    email: string;
    age?: number;
}

interface CreateUserResponse {
    id: number;
    success: boolean;
    message: string;
}

const request: CreateUserRequest = {
    name: 'Jane Smith',
    email: 'jane@example.com',
    age: 30
};

$.post('/api/users', request).done((response: CreateUserResponse) => {
    if (response.success) {
        console.log(`User created with ID: ${response.id}`);
    } else {
        console.error('Error:', response.message);
    }
});

JSON Requests

// GET JSON data
$.getJSON('/api/config')
    .done(config => {
        console.log('Configuration:', config);
    })
    .fail(() => {
        console.log('Failed to load configuration');
    });

// GET JSON with parameters
$.getJSON('/api/search', { q: 'javascript', limit: 5 })
    .done(results => {
        console.log('Search results:', results);
    });

// Type-safe JSON request
interface SearchResult {
    title: string;
    url: string;
    snippet: string;
}

interface SearchResponse {
    results: SearchResult[];
    total: number;
    page: number;
}

$.getJSON('/api/search', { q: 'typescript' })
    .done((response: SearchResponse) => {
        console.log(`Found ${response.total} results:`);
        response.results.forEach(result => {
            console.log(`- ${result.title}: ${result.url}`);
        });
    });

Advanced AJAX Configuration

Full AJAX Configuration

// Complete AJAX request configuration
$.ajax({
    url: '/api/users',
    method: 'POST',
    contentType: 'application/json',
    dataType: 'json',
    data: JSON.stringify({
        name: 'Alice Johnson',
        email: 'alice@example.com'
    }),
    headers: {
        'X-API-Key': 'your-api-key',
        'X-Request-ID': generateRequestId()
    },
    timeout: 5000,
    beforeSend: function(xhr, settings) {
        console.log('Sending request to:', settings.url);
        xhr.setRequestHeader('Authorization', 'Bearer ' + getAuthToken());
    },
    success: function(data, textStatus, xhr) {
        console.log('Success:', data);
        console.log('Status:', textStatus);
        console.log('Response headers:', xhr.getAllResponseHeaders());
    },
    error: function(xhr, textStatus, errorThrown) {
        console.error('Error:', textStatus, errorThrown);
        console.error('Response:', xhr.responseText);
    },
    complete: function(xhr, textStatus) {
        console.log('Request completed with status:', textStatus);
    }
});

// AJAX with custom context
const apiClient = {
    baseUrl: '/api/v1',
    token: 'auth-token',
    
    request: function(endpoint: string, data: any) {
        return $.ajax({
            url: this.baseUrl + endpoint,
            method: 'POST',
            data: JSON.stringify(data),
            contentType: 'application/json',
            headers: {
                'Authorization': `Bearer ${this.token}`
            },
            context: this,
            success: this.handleSuccess,
            error: this.handleError
        });
    },
    
    handleSuccess: function(data: any) {
        console.log('API success:', data);
    },
    
    handleError: function(xhr: JQuery.jqXHR) {
        console.error('API error:', xhr.status, xhr.responseText);
    }
};

File Upload

// File upload with FormData
function uploadFile(file: File) {
    const formData = new FormData();
    formData.append('file', file);
    formData.append('category', 'documents');
    
    return $.ajax({
        url: '/api/upload',
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false,
        xhr: function() {
            const xhr = new XMLHttpRequest();
            
            // Upload progress
            xhr.upload.addEventListener('progress', (event) => {
                if (event.lengthComputable) {
                    const percentComplete = (event.loaded / event.total) * 100;
                    console.log(`Upload progress: ${percentComplete}%`);
                }
            });
            
            return xhr;
        },
        success: function(response) {
            console.log('Upload successful:', response);
        },
        error: function(xhr) {
            console.error('Upload failed:', xhr.responseText);
        }
    });
}

// Multiple file upload
function uploadMultipleFiles(files: FileList) {
    const formData = new FormData();
    
    Array.from(files).forEach((file, index) => {
        formData.append(`files[${index}]`, file);
    });
    
    return $.ajax({
        url: '/api/upload-multiple',
        type: 'POST',
        data: formData,
        processData: false,
        contentType: false
    });
}

Error Handling and Status Codes

Comprehensive Error Handling

// Detailed error handling
$.ajax({
    url: '/api/data',
    method: 'GET',
    timeout: 10000,
    statusCode: {
        200: function() {
            console.log('Success!');
        },
        404: function() {
            console.log('Resource not found');
        },
        500: function() {
            console.log('Server error');
        }
    }
}).done(function(data) {
    // Success handler
    console.log('Data received:', data);
}).fail(function(xhr, textStatus, errorThrown) {
    // Error handler
    switch (textStatus) {
        case 'timeout':
            console.error('Request timed out');
            break;
        case 'abort':
            console.error('Request was aborted');
            break;
        case 'error':
            console.error('HTTP error:', xhr.status, errorThrown);
            break;
        case 'parsererror':
            console.error('Failed to parse response');
            break;
        default:
            console.error('Unknown error:', textStatus);
    }
}).always(function() {
    console.log('Request completed');
});

// Global error handler
$(document).ajaxError(function(event, xhr, settings, thrownError) {
    console.error('Global AJAX error:', {
        url: settings.url,
        status: xhr.status,
        error: thrownError
    });
});

Retry Logic

// Retry failed requests
function makeRequest(url: string, data: any, maxRetries = 3): Promise<any> {
    let attempts = 0;
    
    function attempt(): Promise<any> {
        return $.ajax({
            url: url,
            method: 'POST',
            data: JSON.stringify(data),
            contentType: 'application/json'
        }).then(
            response => response,
            error => {
                attempts++;
                if (attempts < maxRetries && error.status >= 500) {
                    console.log(`Attempt ${attempts} failed, retrying...`);
                    return new Promise(resolve => {
                        setTimeout(() => resolve(attempt()), 1000 * attempts);
                    });
                }
                throw error;
            }
        );
    }
    
    return attempt();
}

// Usage
makeRequest('/api/save', userData)
    .then(response => console.log('Saved:', response))
    .catch(error => console.error('Failed after retries:', error));

Request Transformation and Validation

Data Transformation

// Request data transformation
$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        // Add timestamp to all requests
        if (settings.data) {
            const separator = settings.data.includes('?') ? '&' : '?';
            settings.data += separator + 'timestamp=' + Date.now();
        }
    },
    
    dataFilter: function(data, type) {
        // Transform response data
        if (type === 'json') {
            const parsed = JSON.parse(data);
            // Add metadata to all responses
            parsed._meta = {
                receivedAt: new Date().toISOString(),
                processed: true
            };
            return JSON.stringify(parsed);
        }
        return data;
    }
});

// Custom data converter
$.ajaxSetup({
    converters: {
        "text json": function(data) {
            // Custom JSON parser with error handling
            try {
                return JSON.parse(data);
            } catch (e) {
                console.error('JSON parse error:', e);
                return { error: 'Invalid JSON response' };
            }
        }
    }
});

Request Validation

// Request validation wrapper
function validateAndSend<T>(options: JQuery.AjaxSettings, validator?: (data: any) => boolean): JQuery.jqXHR {
    if (validator && options.data && !validator(options.data)) {
        const deferred = $.Deferred();
        deferred.reject('Validation failed');
        return deferred.promise() as JQuery.jqXHR;
    }
    
    return $.ajax(options);
}

// Email validation example
function isValidEmail(email: string): boolean {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

const userData = { name: 'John', email: 'john@example.com' };

validateAndSend({
    url: '/api/users',
    method: 'POST',
    data: userData
}, (data) => {
    return data.name && data.email && isValidEmail(data.email);
}).done(response => {
    console.log('User created:', response);
}).fail(error => {
    console.error('Validation or request failed:', error);
});

Cross-Origin Requests and JSONP

CORS Configuration

// Cross-origin request with credentials
$.ajax({
    url: 'https://api.external.com/data',
    method: 'GET',
    crossDomain: true,
    xhrFields: {
        withCredentials: true
    },
    headers: {
        'Authorization': 'Bearer ' + token
    }
}).done(data => {
    console.log('External data:', data);
});

// Preflight request handling
$.ajax({
    url: 'https://api.external.com/submit',
    method: 'PUT',
    contentType: 'application/json',
    data: JSON.stringify(payload),
    beforeSend: function(xhr) {
        // Custom headers for CORS preflight
        xhr.setRequestHeader('X-Custom-Header', 'value');
    }
});

JSONP Requests

// JSONP for cross-domain requests
$.ajax({
    url: 'https://api.external.com/data',
    dataType: 'jsonp',
    jsonp: 'callback',
    success: function(data) {
        console.log('JSONP data:', data);
    },
    error: function() {
        console.log('JSONP request failed');
    }
});

// JSONP with custom callback name
$.ajax({
    url: 'https://api.external.com/data',
    dataType: 'jsonp',
    jsonpCallback: 'myCustomCallback',
    success: function(data) {
        console.log('Data via custom callback:', data);
    }
});

// $.getJSON with JSONP (automatic detection)
$.getJSON('https://api.external.com/data?callback=?')
    .done(data => console.log('JSONP data:', data))
    .fail(() => console.log('JSONP failed'));

Global AJAX Configuration

Setup and Defaults

// Global AJAX configuration
$.ajaxSetup({
    timeout: 30000,
    cache: false,
    contentType: 'application/json',
    beforeSend: function(xhr, settings) {
        // Add auth token to all requests
        const token = localStorage.getItem('authToken');
        if (token) {
            xhr.setRequestHeader('Authorization', `Bearer ${token}`);
        }
        
        // Add CSRF token
        const csrfToken = $('meta[name="csrf-token"]').attr('content');
        if (csrfToken) {
            xhr.setRequestHeader('X-CSRF-Token', csrfToken);
        }
    }
});

// Global event handlers
$(document).ajaxStart(function() {
    $('#loading-indicator').show();
});

$(document).ajaxStop(function() {
    $('#loading-indicator').hide();
});

$(document).ajaxSuccess(function(event, xhr, settings) {
    console.log('AJAX success:', settings.url);
});

$(document).ajaxError(function(event, xhr, settings, thrownError) {
    console.error('AJAX error:', settings.url, xhr.status, thrownError);
    
    // Handle common errors globally
    if (xhr.status === 401) {
        // Redirect to login
        window.location.href = '/login';
    } else if (xhr.status === 403) {
        alert('Access denied');
    }
});

Performance and Optimization

Request Caching and Optimization

// Request deduplication
const requestCache = new Map<string, Promise<any>>();

function cachedAjax(url: string, options: JQuery.AjaxSettings = {}): Promise<any> {
    const cacheKey = url + JSON.stringify(options);
    
    if (requestCache.has(cacheKey)) {
        return requestCache.get(cacheKey)!;
    }
    
    const promise = $.ajax({ url, ...options }).promise();
    requestCache.set(cacheKey, promise);
    
    // Clear cache after 5 minutes
    setTimeout(() => requestCache.delete(cacheKey), 5 * 60 * 1000);
    
    return promise;
}

// Batch requests
function batchRequests<T>(requests: Array<() => JQuery.jqXHR>): Promise<T[]> {
    return Promise.all(requests.map(req => req().promise()));
}

// Usage
const userRequests = [
    () => $.get('/api/users/1'),
    () => $.get('/api/users/2'),
    () => $.get('/api/users/3')
];

batchRequests(userRequests).then(users => {
    console.log('All users loaded:', users);
});

// Request queuing for rate limiting
class RequestQueue {
    private queue: Array<() => JQuery.jqXHR> = [];
    private processing = false;
    private readonly delay = 100; // ms between requests
    
    add(requestFn: () => JQuery.jqXHR): Promise<any> {
        return new Promise((resolve, reject) => {
            this.queue.push(() => {
                return requestFn().done(resolve).fail(reject);
            });
            this.process();
        });
    }
    
    private async process() {
        if (this.processing || this.queue.length === 0) return;
        
        this.processing = true;
        
        while (this.queue.length > 0) {
            const request = this.queue.shift()!;
            request();
            await new Promise(resolve => setTimeout(resolve, this.delay));
        }
        
        this.processing = false;
    }
}

The AJAX system provides comprehensive HTTP communication capabilities with full TypeScript support, enabling robust client-server interactions with proper error handling, type safety, and performance optimization.