CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-reqwest

A wrapper for asynchronous HTTP requests supporting XMLHttpRequest, JSONP, CORS, and CommonJS Promises

Pending
Overview
Eval results
Files

promise-interface.mddocs/

Promise Interface

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.

Capabilities

Then Method

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);
  });

Fail Method

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');
  });

Always Method

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();
  });

Catch Method

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);
  });

Method Chaining Patterns

The promise-like interface supports various chaining patterns for complex async workflows:

Sequential Requests

// 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');
  });

Error Recovery

// 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);
  });

Conditional Processing

// 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);
  });

Parallel Processing Simulation

// 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);

Abort Method

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();
});

Retry Method

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();
    }
  });

Callback Function Signatures

The promise interface callbacks receive specific parameters:

Success Callback

/**
 * Success callback function signature
 * @param {any} response - Parsed response data (JSON object, XML document, HTML, text, etc.)
 */
type SuccessCallback = (response: any) => any;

Failure Callback

/**
 * 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

/**
 * 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

/**
 * 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;

Integration with Traditional Callbacks

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

docs

core-requests.md

index.md

jquery-compat.md

promise-interface.md

utilities.md

tile.json