UNPKG

@empathyco/x-components

Version:
75 lines (72 loc) 2.84 kB
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