A wrapper for asynchronous HTTP requests supporting XMLHttpRequest, JSONP, CORS, and CommonJS Promises
—
Chainable promise-like methods for handling request success, failure, and completion with modern async patterns. The request object returned by reqwest() provides methods that allow for elegant error handling and response processing.
Handles successful and failed requests with optional separate callbacks.
/**
* Handles successful and failed requests
* @param {Function} success - Success callback function
* @param {Function} fail - Optional failure callback function
* @returns {Object} Self for chaining
*/
then(success?: Function, fail?: Function): RequestPromise;Usage Examples:
// Success only
reqwest({ url: '/api/data' })
.then(function(response) {
console.log('Data received:', response);
});
// Success and failure
reqwest({ url: '/api/data' })
.then(
function(response) {
console.log('Success:', response);
},
function(xhr, type, error) {
console.log('Failed:', error);
}
);
// Chaining multiple then calls
reqwest({ url: '/api/users' })
.then(function(users) {
console.log('Got users:', users.length);
return reqwest({ url: '/api/posts' });
})
.then(function(posts) {
console.log('Got posts:', posts.length);
});Handles only failed requests, allowing for focused error handling.
/**
* Handles failed requests only
* @param {Function} fn - Failure callback function
* @returns {Object} Self for chaining
*/
fail(fn: Function): RequestPromise;Usage Examples:
// Basic error handling
reqwest({ url: '/api/data' })
.fail(function(xhr, type, error) {
console.log('Request failed:', error);
console.log('Status:', xhr.status);
console.log('Error type:', type);
});
// Error handling with retry logic
reqwest({ url: '/api/unreliable' })
.fail(function(xhr, type, error) {
if (xhr.status === 503) {
console.log('Service unavailable, retrying in 2 seconds...');
setTimeout(() => {
this.retry();
}, 2000);
} else {
console.log('Permanent failure:', error);
}
});
// Multiple error handlers
reqwest({ url: '/api/data' })
.fail(function(xhr, type, error) {
console.log('Logging error:', error);
})
.fail(function(xhr, type, error) {
showUserErrorMessage('Failed to load data');
});Executes callback regardless of success or failure, useful for cleanup operations.
/**
* Executes callback regardless of success or failure
* @param {Function} fn - Callback function always executed
* @returns {Object} Self for chaining
*/
always(fn: Function): RequestPromise;Usage Examples:
// Cleanup operations
reqwest({ url: '/api/data' })
.always(function(xhr, type) {
hideLoadingSpinner();
console.log('Request completed with type:', type);
});
// Multiple always handlers
reqwest({ url: '/api/user-profile' })
.then(function(profile) {
updateUserInterface(profile);
})
.fail(function(xhr, type, error) {
showErrorMessage(error);
})
.always(function() {
enableFormSubmission();
updateLastRequestTime();
});Alias for the fail() method, providing familiar promise-style error handling.
/**
* Handles failed requests (alias for fail method)
* @param {Function} fn - Failure callback function
* @returns {Object} Self for chaining
*/
catch(fn: Function): RequestPromise;Usage Examples:
// Promise-style error handling
reqwest({ url: '/api/data' })
.then(function(data) {
return processData(data);
})
.catch(function(xhr, type, error) {
console.log('Something went wrong:', error);
});
// Equivalent to using fail()
reqwest({ url: '/api/data' })
.catch(function(xhr, type, error) {
// Same as .fail(function(xhr, type, error) { ... })
handleError(error);
});The promise-like interface supports various chaining patterns for complex async workflows:
// Load user, then user's posts, then post comments
reqwest({ url: '/api/user/123' })
.then(function(user) {
console.log('Loaded user:', user.name);
return reqwest({ url: `/api/user/${user.id}/posts` });
})
.then(function(posts) {
console.log('Loaded posts:', posts.length);
if (posts.length > 0) {
return reqwest({ url: `/api/post/${posts[0].id}/comments` });
}
})
.then(function(comments) {
if (comments) {
console.log('Loaded comments:', comments.length);
}
})
.catch(function(xhr, type, error) {
console.log('Pipeline failed:', error);
})
.always(function() {
console.log('Request pipeline complete');
});// Attempt primary endpoint, fallback to secondary
reqwest({ url: '/api/primary/data' })
.fail(function(xhr, type, error) {
console.log('Primary failed, trying fallback...');
return reqwest({ url: '/api/fallback/data' });
})
.then(function(data) {
console.log('Data loaded (from primary or fallback):', data);
})
.catch(function(xhr, type, error) {
console.log('Both endpoints failed:', error);
});// Load data and conditionally make additional requests
reqwest({ url: '/api/initial-data' })
.then(function(data) {
console.log('Initial data loaded');
if (data.needsAdditionalData) {
return reqwest({ url: '/api/additional-data' });
} else {
return data; // Return original data if no additional request needed
}
})
.then(function(finalData) {
console.log('Final data ready:', finalData);
})
.catch(function(xhr, type, error) {
console.log('Request chain failed:', error);
});// Simulate parallel requests (though each reqwest call is independent)
const userRequest = reqwest({ url: '/api/user/123' });
const postsRequest = reqwest({ url: '/api/posts' });
const settingsRequest = reqwest({ url: '/api/settings' });
let userData, postsData, settingsData;
let completedRequests = 0;
function checkAllComplete() {
completedRequests++;
if (completedRequests === 3) {
console.log('All data loaded:', { userData, postsData, settingsData });
}
}
userRequest
.then(function(data) { userData = data; })
.always(checkAllComplete);
postsRequest
.then(function(data) { postsData = data; })
.always(checkAllComplete);
settingsRequest
.then(function(data) { settingsData = data; })
.always(checkAllComplete);Aborts the current request and triggers failure callbacks.
/**
* Aborts the current request
* @returns {Object} Self for chaining (though aborted requests can't continue)
*/
abort(): RequestPromise;Usage Examples:
// Abort after timeout
const request = reqwest({ url: '/api/large-data' });
setTimeout(function() {
request.abort();
console.log('Request aborted due to timeout');
}, 5000);
// Conditional abort
const uploadRequest = reqwest({
url: '/api/upload',
method: 'POST',
data: formData
});
// Cancel upload if user navigates away
window.addEventListener('beforeunload', function() {
uploadRequest.abort();
});Retries the request with the same options and configuration.
/**
* Retries the request with the same options
* @returns {Object} New request object for the retry attempt
*/
retry(): RequestPromise;Usage Examples:
// Retry on server errors
let retryCount = 0;
const maxRetries = 3;
function makeRequest() {
return reqwest({ url: '/api/unreliable' })
.fail(function(xhr, type, error) {
if (xhr.status >= 500 && retryCount < maxRetries) {
retryCount++;
console.log(`Server error, retrying... (${retryCount}/${maxRetries})`);
setTimeout(() => {
makeRequest();
}, 1000 * retryCount); // Exponential backoff
} else {
console.log('Max retries reached or permanent error:', error);
}
});
}
// Usage with instance retry method
reqwest({ url: '/api/data' })
.fail(function(xhr, type, error) {
if (xhr.status === 503) {
console.log('Service unavailable, retrying...');
return this.retry();
}
});The promise interface callbacks receive specific parameters:
/**
* Success callback function signature
* @param {any} response - Parsed response data (JSON object, XML document, HTML, text, etc.)
*/
type SuccessCallback = (response: any) => any;/**
* Failure callback function signature
* @param {XMLHttpRequest} xhr - The XMLHttpRequest object that failed
* @param {string} message - Error message ('Request is aborted: timeout', 'Could not parse JSON', etc.)
* @param {any} error - Additional error context (parsing errors, etc.)
*/
type FailCallback = (xhr: XMLHttpRequest, message: string, error: any) => any;/**
* Always callback function signature (called on both success and failure)
* @param {any} response - Response data (same as success callback) or XMLHttpRequest object (on error)
*/
type AlwaysCallback = (response: any) => void;/**
* Before callback function signature (called before request is sent)
* @param {XMLHttpRequest} xhr - The XMLHttpRequest object before the request is sent
*/
type BeforeCallback = (xhr: XMLHttpRequest) => void;The promise-like interface works alongside traditional callback options:
// Using both promise methods and traditional callbacks
reqwest({
url: '/api/data',
success: function(data) {
console.log('Traditional success callback');
},
error: function(xhr, type, err) {
console.log('Traditional error callback');
}
})
.then(function(data) {
console.log('Promise-style success');
})
.catch(function(xhr, type, err) {
console.log('Promise-style error');
})
.always(function() {
console.log('Promise-style cleanup');
});Both callback styles will be executed, allowing for gradual migration to promise-style code while maintaining backward compatibility.
Install with Tessl CLI
npx tessl i tessl/npm-reqwest