Skip to content

Instantly share code, notes, and snippets.

@SugarDarius
Last active September 10, 2020 03:35
Show Gist options
  • Save SugarDarius/45277e3b445b26c3b255a888b22ba3c2 to your computer and use it in GitHub Desktop.
Save SugarDarius/45277e3b445b26c3b255a888b22ba3c2 to your computer and use it in GitHub Desktop.
An async promise middleware for Redux written in TypeScript
/*
* Async action
* author: Aurélien Dupays Dexemple
*/
import { AxiosStatic, AxiosResponse } from 'axios';
import { SyncAction } from './sync-action';
export interface AsyncAction<R extends string = '', S extends string = '', F extends string = '', P extends { [ key: string ]: any } = {}> extends SyncAction<'@@async/action', P> {
types: Array<R | S | F>;
promise: (axios: AxiosStatic) => Promise<AxiosResponse>;
}
/*
* Async promise middleware
* author: Aurélien Dupays Dexemple
*/
import { Middleware, Dispatch } from 'redux';
import { AxiosResponse } from 'axios';
import { AsyncAction, SyncAction } from '../types';
import { GetAxios } from '../../utils';
function isAsyncAction(action: SyncAction | AsyncAction): action is AsyncAction {
return (<AsyncAction>action).types !== undefined && (<AsyncAction>action).promise !== undefined;
}
export const asyncPromiseMiddleware: Middleware = () => (next: Dispatch<SyncAction>) => async (action: SyncAction | AsyncAction): Promise<SyncAction> => {
if (!isAsyncAction(action)) {
return await next(action);
}
else {
const { promise, types, payload } = action;
const [ REQUEST, SUCCESS, FAILURE ] = types;
next({ type: REQUEST, payload });
try {
const response: AxiosResponse = await promise(GetAxios(true, 30000));
return await next({ type: SUCCESS, result: response.data, payload });
}
catch (error) {
return await next({ type: FAILURE, error, payload });
}
}
}
/*
* Get axios
* author: Aurélien Dupays Dexemple
*/
import axios, { AxiosStatic, AxiosRequestConfig, AxiosResponse } from 'axios';
export const GetAxios = (withCredentialsOpts: boolean, timeoutOpts: number): AxiosStatic => {
axios.interceptors.request.use(({ timeout, withCredentials, ...rest }: AxiosRequestConfig) => ({
timeout: timeoutOpts,
withCredentials: withCredentialsOpts,
...rest
}));
axios.interceptors.response.use((response: AxiosResponse) => response, (err: any) => Promise.reject(err));
return axios;
}
/*
* Sync action
* author: Aurélien Dupays Dexemple
*/
import * as Redux from 'redux';
export type SyncActionJsonObjectAsyncResult = { [ key: string ]: any };
export type SyncActionJsonArrayAsyncResult = any[];
export interface SyncAction<T extends string = '', P extends { [key: string]: any } = {}> extends Redux.Action<T> {
result?: SyncActionJsonObjectAsyncResult | SyncActionJsonArrayAsyncResult;
error?: { [key: string]: any };
payload?: P;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment