marmelab / react-admin

A frontend Framework for single-page applications on top of REST/GraphQL APIs, using TypeScript, React and Material Design
http://marmelab.com/react-admin
MIT License
24.89k stars 5.24k forks source link

Custom save after submission with returnPromise not redirecting #5992

Closed newfylox closed 11 months ago

newfylox commented 3 years ago

What you were expecting: When following this example https://marmelab.com/react-admin/CreateEdit.html#submission-validation without making any changes, I can easily display the errors based on my API response as expected. When a submission is valid, I expect the record to be created and react-admin to redirect the user to the edit form because I don't overwrite props.

What happened instead: The record is created, but the page doesn't change. All form fields are still filled and no redirection is happening. Perhaps the option returnPromise: true has not the responsibility to tell the CreateForm to redirect?

Environment

djhi commented 3 years ago

Thanks for reporting this. Please provide a sample application showing the issue by forking the following CodeSandbox (https://codesandbox.io/s/github/marmelab/react-admin/tree/master/examples/simple).

newfylox commented 3 years ago

@djhi Yeah sure. Here's a sample you can even edit. It basically replicates the code from the documentation I sent you before. The "undoable" props changes nothing, whether it's true or false.

https://codesandbox.io/s/condescending-glade-mknpm?file=/src/posts.js

djhi commented 3 years ago

Ok so the documentation is both wrong and incomplete.

Wrong because Create does not support undoable mutations, and incomplete because providing your own save function means that you have to handle side effects yourself, including redirecting to another page.

newfylox commented 3 years ago

Yeah, the undoable thing was bothering me at the beginning because I never saw this option on Create before.

Should we use onSuccess and onFailure instead of a try catch block? Also, is there generic Classes/Functions we can import from react-admin to replicate the side effects and redirecting without copying the whole code from the source code? For example, import functions and give some parameters to have the default save behavior?

djhi commented 3 years ago

No, we haven't extracted this into a reusable thing outside the createController. Marking this as an enhancement

newfylox commented 3 years ago

Alright. I don't want to create a new Issue (probably I should) and I know it's out of scope, but is it normal that hidden attribute on any form inputs does nothing?

I just noticed that it works on List but not in Create or Edit

apourzand commented 3 years ago

I was able to redirect to edit the Server-Side Validation example using the onSuccess Method as following:

export const UserCreate = (props) => {
  const [mutate] = useMutation();
  const redirect = useRedirect();
  const save = useCallback(
    async (values) => {
      try {
        await mutate({
          type: 'create',
          resource: 'user',
          payload: { data: values },
        }, { 
          returnPromise: true,
          onSuccess: (data) => {
            redirect('edit', '/user', data['data']['id']);
          } 
        });
      } catch (error) {
        return error.body
      }
    },
    [mutate, redirect]
  );

  return (
    <Create undoable="false" {...props}>
      <SimpleForm save={save}>
        <TextInput source="firstName" />
        <TextInput source="lastName" />
        <TextInput source="email" />
      </SimpleForm>
    </Create>
  );
};

Hope this will help.

hlubek commented 2 years ago

I think the docs are a bit misleading since a custom save function and using useMutation and passing returnPromise: true enables support for responding with errors. But it does not implement all the handling of onSuccess, onFailure, transform, redirect, etc.. There's also no correct "saving" handling since an extra mutation is used.

To really use server validation for all resources this would mean a lot of code or replicating the code in Create (or Edit) to make it generic (which certainly would break on a future update).

I think there should be a prop/option that is forwarded from Create / Edit to the useCreate / useUpdate hook (which sets returnPromise: true) and then apply a user-defined function to transform a possible error (I haven't tested if onFailure already allows to do this). This would allow to use the default controller logic with only minimal additional code for server validation.

fzaninotto commented 11 months ago

React-admin version 3 is in maintenance mode and won't receive any new feature. React-admin v4 does support server-side validation and async submission, so you can solve your problem by upgrading to react-admin v4.