mantine icon indicating copy to clipboard operation
mantine copied to clipboard

The form error appears and disappears when I press submit.

Open kolobok001 opened this issue 10 months ago • 4 comments

Dependencies check up

  • [X] I have verified that I use latest version of all @mantine/* packages

What version of @mantine/* packages do you have in package.json?

7.8.0

What package has an issue?

@mantine/form

What framework do you use?

Vite

In which browsers you can reproduce the issue?

All

Describe the bug

I have a form. When I click on the confirm button, I clear all errors and make a request to the server. With some answer, I need to put an error in the field, but the error appears and disappears one by one.

If possible, include a link to a codesandbox with a minimal reproduction

https://codesandbox.io/p/sandbox/mantine-7-8-form-error-rpnxw7

Possible fix

No response

Self-service

  • [ ] I would be willing to implement a fix for this issue

kolobok001 avatar Apr 18 '24 05:04 kolobok001

I do not understand the issue. It works exactly as coded in the sandbox

rtivital avatar Apr 18 '24 05:04 rtivital

I do not understand the issue. It works exactly as coded in the sandbox

Ok I renewed sandbox. Removed clearErrors. I expect that the error message when clicking the button will always be displayed. This was the case in previous versions of mantine. Now, the first time I click, an error appears. On the second press it disappears, although it should have remained

kolobok001 avatar Apr 18 '24 06:04 kolobok001

It work how I expected in version 7.7.2. Forked box https://codesandbox.io/p/sandbox/mantine-7-8-form-error-forked-d6kxc2

kolobok001 avatar Apr 18 '24 06:04 kolobok001

I have the same problem. An error set via form.setFieldError seems to be ignored in the next submit event.

Current workaround that works for me:

const onSubmit = () => {
  if (Object.keys(form.errors).length !== 0) {
      form.setErrors(form.errors); // otherwise Mantine will "forget" the current errors that still exist
      return;
  }
};

thomasdondorf avatar May 15 '24 12:05 thomasdondorf

form.onSubmit calls form.validate under the hood and resets errors state if all fields are valid. This causes a race condition (which is not fixable) and an issue with stale errors state (which will be fixed in the next patch).

Things that you can do in next patch:

form.onSubmit(() => {
  // async operation to update error state. It can be Promise.resolve for sync operation to show error instantly
  Promise.resolve().then(() => form.setFieldError('email', 'Server error'));
});

rtivital avatar May 24 '24 08:05 rtivital

Thank your for answering and thanks for this great library!

Maybe it would be more beneficial to check if the value was changed?

Here is a common example where this is relevant. Imagine a registration form with a user name login. User names need to be unique, so that the server might respond with an error if the name is already taken.

Minimal code example:

const form = useForm({
    initialValues: {
        username: '',
        // ...
    },
});

async function submit(data) {
    const answer = await makeRequestSomehow();
    if (answer.errorUserNameIsAlreadyInUse) {
        form.setFieldError('username', 'Sorry, your username is already in use.');
    }
}

I think the best developer experience would be to simply keep the error for username if the value was not changed.

thomasdondorf avatar May 25 '24 09:05 thomasdondorf

There should not be any issue with async operations with the next patch – the error will be set to the given value in your example. The only issue that will remain is sync operations.

rtivital avatar May 25 '24 09:05 rtivital

I see. Thanks for clarifying! :)

thomasdondorf avatar May 25 '24 10:05 thomasdondorf

Fixed in 7.10.1

rtivital avatar May 30 '24 10:05 rtivital