Skip to content

Instantly share code, notes, and snippets.

@Maqsim
Last active October 28, 2024 21:14
Show Gist options
  • Save Maqsim/29cd00e32c56c307d06f9a23f10fb668 to your computer and use it in GitHub Desktop.
Save Maqsim/29cd00e32c56c307d06f9a23f10fb668 to your computer and use it in GitHub Desktop.
A non-block promise wrapper fro axios/fetch
import type { AxiosError, AxiosPromise } from 'axios';
type Result<T> = [AxiosError, null] | [null, T];
type AllResult<T> = [AxiosError, null] | [null, T[]];
/**
* Wraps an Axios promise to return a tuple with either the error or the response data.
*
* @template T - The type of the response data.
* @param {AxiosPromise<T>} promise - The Axios promise to wrap.
* @returns {Promise<Result<T>>} A promise that resolves to a tuple containing either the error or the response data.
*
* @example
* const [error, data] = await promiseWrapper(axios.get('/api/data'));
* if (error) {
* console.error('Request failed', error);
* } else {
* console.log('Request succeeded', data);
* }
*/
export const promiseWrapper = async <T>(promise: AxiosPromise<T>): Promise<Result<T>> => {
try {
const response = await promise;
return [null, response.data];
} catch (error) {
return [error as AxiosError, null];
}
};
/**
* Wraps multiple promises and returns a tuple with either the first error encountered or an array of all response data.
*
* @template T - The type of the response data.
* @param {Iterable<Promise<Result<any>>>} wrappedPromises - An iterable of wrapped promises to resolve.
* @returns {Promise<AllResult<any>>} A promise that resolves to a tuple containing either the first error encountered or an array of all response data.
*
* @example
* const promises = [promiseWrapper(axios.get('/api/data1')), promiseWrapper(axios.get('/api/data2'))];
* const [error, data] = await promiseWrapperAll(promises);
* if (error) {
* console.error('One or more requests failed', error);
* } else {
* console.log('All requests succeeded', data);
* }
*/
export const promiseWrapperAll = async <T>(
wrappedPromises: Iterable<Promise<Result<any>>>
): Promise<AllResult<any>> => {
const results = await Promise.all(wrappedPromises);
const errors = results.filter(([error]) => error !== null) as [AxiosError, null][];
if (errors.length > 0) {
return [errors[0][0], null];
}
return [null, results.map(([, data]) => data as T)];
};
// EXAMPLE
const fetchUsers = promiseWrapper(axios.get('/users'));
const [error, users] = await fetchUsers();
if (error) {
console.error(error);
return;
}
console.log(users);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment