diff --git a/packages/ra-core/src/dataProvider/useMutation.ts b/packages/ra-core/src/dataProvider/useMutation.ts index 20c5bf24426..6996547bf87 100644 --- a/packages/ra-core/src/dataProvider/useMutation.ts +++ b/packages/ra-core/src/dataProvider/useMutation.ts @@ -31,6 +31,7 @@ import useDataProviderWithDeclarativeSideEffects from './useDataProviderWithDecl * @param {Object} options * @param {string} options.action Redux action type * @param {boolean} options.undoable Set to true to run the mutation locally before calling the dataProvider + * @param {boolean} options.returnPromise Set to true to return the result promise of the mutation * @param {Function} options.onSuccess Side effect function to be executed upon success or failure, e.g. { onSuccess: response => refresh() } } * @param {Function} options.onFailure Side effect function to be executed upon failure, e.g. { onFailure: error => notify(error.message) } } * @param {boolean} options.withDeclarativeSideEffectsSupport Set to true to support legacy side effects (e.g. { onSuccess: { refresh: true } }) @@ -52,6 +53,7 @@ import useDataProviderWithDeclarativeSideEffects from './useDataProviderWithDecl * - {Object} options * - {string} options.action Redux action type * - {boolean} options.undoable Set to true to run the mutation locally before calling the dataProvider + * - {boolean} options.returnPromise Set to true to return the result promise of the mutation * - {Function} options.onSuccess Side effect function to be executed upon success or failure, e.g. { onSuccess: response => refresh() } } * - {Function} options.onFailure Side effect function to be executed upon failure, e.g. { onFailure: error => notify(error.message) } } * - {boolean} withDeclarativeSideEffectsSupport Set to true to support legacy side effects (e.g. { onSuccess: { refresh: true } }) @@ -156,14 +158,17 @@ const useMutation = ( setState(prevState => ({ ...prevState, loading: true })); - finalDataProvider[params.type] + const returnPromise = options && options.returnPromise; + + const promise = finalDataProvider[params.type] .apply( finalDataProvider, typeof params.resource !== 'undefined' ? [params.resource, params.payload, params.options] : [params.payload, params.options] ) - .then(({ data, total }) => { + .then(response => { + const { data, total } = response; setState({ data, error: null, @@ -171,6 +176,9 @@ const useMutation = ( loading: false, total, }); + if (returnPromise) { + return response; + } }) .catch(errorFromResponse => { setState({ @@ -180,7 +188,14 @@ const useMutation = ( loading: false, total: null, }); + if (returnPromise) { + throw errorFromResponse; + } }); + + if (returnPromise) { + return promise; + } }, [ // deep equality, see https://github.com/facebook/react/issues/14476#issuecomment-471199055 @@ -204,6 +219,7 @@ export interface Mutation { export interface MutationOptions { action?: string; undoable?: boolean; + returnPromise?: boolean; onSuccess?: (response: any) => any | Object; onFailure?: (error?: any) => any | Object; withDeclarativeSideEffectsSupport?: boolean; diff --git a/packages/ra-core/src/form/FormWithRedirect.tsx b/packages/ra-core/src/form/FormWithRedirect.tsx index 65109c64743..4d9bd611af9 100644 --- a/packages/ra-core/src/form/FormWithRedirect.tsx +++ b/packages/ra-core/src/form/FormWithRedirect.tsx @@ -111,9 +111,9 @@ const FormWithRedirect: FC = ({ finalInitialValues, values ); - onSave.current(sanitizedValues, finalRedirect); + return onSave.current(sanitizedValues, finalRedirect); } else { - onSave.current(values, finalRedirect); + return onSave.current(values, finalRedirect); } };