@empathyco/x-components
Version:
Empathy X Components
75 lines (72 loc) • 2.84 kB
JavaScript
import { cancellablePromise, CancelSymbol } from '../../utils/cancellable-promise.js';
/**
* Utility to create an action that requests and save some data asynchronously, with the
* option to cancel the request at any moment. This factory provides with the standard flow
* for requesting, cancelling, handling errors for a module, while also taking care of its status.
*
* @param hooks - The {@link FetchAndSaveHooks} hooks to create the action.
* @public
* @returns An action to fetch and save some data, and an action to cancel the last request.
*/
function createFetchAndSaveActions({ fetch, onSuccess, onError = console.error, onCancel, }) {
let cancelPreviousRequest;
/**
* Called asynchronously after a response has been received.
*
* @param context - The {@link https://vuex.vuejs.org/guide/actions.html | context} of the
* actions, provided by Vuex.
* @param response - The fetch response.
* @returns A Promise that resolves after handling the response.
*/
async function handleResponse(context, response) {
return Promise.resolve(onSuccess(context, response)).then(() => {
context.commit('setStatus', 'success');
});
}
/**
* Called immediately after a request has been cancelled.
*
* @param context - The {@link https://vuex.vuejs.org/guide/actions.html | context} of the
* actions, provided by Vuex.
*/
function handleCancel(context) {
cancelPreviousRequest = undefined;
context.commit('setStatus', 'success');
onCancel?.();
}
/**
* Called asynchronously whenever an error happens in the fetch and save flow.
*
* @param context - The {@link https://vuex.vuejs.org/guide/actions.html | context} of the
* actions, provided by Vuex.
* @param error - The error information.
*/
function handleError(context, error) {
if (error !== CancelSymbol) {
context.commit('setStatus', 'error');
onError(error);
}
}
/** @see FetchAndSaveActions.fetchAndSave */
async function fetchAndSave(context, request) {
cancelPrevious();
context.commit('setStatus', 'loading');
const { promise, cancel } = cancellablePromise(fetch(context, request), () => {
handleCancel(context);
});
cancelPreviousRequest = cancel;
return promise
.then(async (response) => handleResponse(context, response))
.catch(error => handleError(context, error));
}
/** @see FetchAndSaveActions.cancelPrevious */
function cancelPrevious() {
cancelPreviousRequest?.();
}
return {
fetchAndSave,
cancelPrevious,
};
}
export { createFetchAndSaveActions };
//# sourceMappingURL=fetch-and-save-action.utils.js.map