Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle Promises from onSave in FormWithRedirect #4703

Closed
oleg-andreyev opened this issue Apr 18, 2020 · 3 comments · Fixed by #5778
Closed

Handle Promises from onSave in FormWithRedirect #4703

oleg-andreyev opened this issue Apr 18, 2020 · 3 comments · Fixed by #5778

Comments

@oleg-andreyev
Copy link
Contributor

oleg-andreyev commented Apr 18, 2020

Is your feature request related to a problem? Please describe.
It's possible to pass custom save prop to EditView or CreateView, it's useful if you want to attach some custom behavior (e.g.: upload images) to submit event (without overriding <Toolbar/>), but currently, it's impossible to handle form submit with Promise API even though final-form supports it
https://github.com/final-form/final-form/blob/ceaf2802184222653afd5f2d4664085e93bb18a6/src/FinalForm.js#L1069-L1092
also "complete" https://github.com/final-form/final-form/blob/ceaf2802184222653afd5f2d4664085e93bb18a6/src/FinalForm.js#L1040 is called immediately a this leads to an issue that "Submit" button is "enabled" even if "custom logic" hasn't finished.

Describe the solution you'd like

onSave.current(finalValues, finalRedirect);
should simply return value from onSave

This will allow returning Promise from onSave handle and attach any async logic without "completing" form submit before async is done.

UPD
Another benefit from this would be returning errors from the backend, if you resolve it with errors
final-form will redirect "errors" for required field
https://github.com/final-form/final-form/blob/ceaf2802184222653afd5f2d4664085e93bb18a6/src/FinalForm.js#L1040-L1060

Example 1

const editController = useEditController(props);

const save = (record, redirectTo, callbacks) => {
    return new Promise((resolve, reject) => {
        editController.save(record, redirectTo, {
            onSuccess: function () {
                // ... any code that you need on success ...
                resolve();
            },
            onFailure: function (error) {
                // ... any code that you need on failure ...
                reject();
            }
        });
    })
};

return (
    <EditView
        {...editController}
        save={save}
    >
        <SimpleForm validateOnBlur={true}>
            <InnerComponent/>
        </SimpleForm>
    </EditView>
);

Example 2 returning errors from JSON-LD backend

onFailure: function (error) {
    const errors = {};
    const type = error.body[0]["@type"][0];

    if (type === `${entrypoint}/docs.jsonld#ConstraintViolationList`) {
        const violations = error.body[0][`${entrypoint}/docs.jsonld#violations`];
        violations.forEach((v) => {
            const key = v[`${entrypoint}/docs.jsonld#propertyPath`][0]['@value'];
            errors[key] = v[`${entrypoint}/docs.jsonld#message`][0]['@value'];
        });
    } else if (type === `http://www.w3.org/ns/hydra/core#Error`) {
        notify(error.body[0]['http://www.w3.org/ns/hydra/core#title'][0]['@value'], 'error', {smart_count: 1});
    }

    // this will cause final-form to render errors.
    resolve(errors);
}
@fzaninotto
Copy link
Member

This is currently not compatible with the way useMutation is implemented, for the failure case. Because for this technique to work, we should not only return the dataProvider Promise, but also re-throw any error caught. While it will work in your case, it will break every other app in case of DataProvider failure, because of the uncaught Error.

This can only be done in an opt-in way, e.g. by passing a returnPromise flag useMutation.

@WiXSL
Copy link
Contributor

WiXSL commented Mar 20, 2021

This one can be closed, right?

@djhi
Copy link
Collaborator

djhi commented Mar 22, 2021

Fixed by #5778

@djhi djhi closed this as completed Mar 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants