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

Cannot clear custom errors when returned by the server #12

Open
fenos opened this issue Jul 15, 2023 · 8 comments
Open

Cannot clear custom errors when returned by the server #12

fenos opened this issue Jul 15, 2023 · 8 comments
Assignees
Labels
enhancement New feature or request

Comments

@fenos
Copy link

fenos commented Jul 15, 2023

Hello, thanks for the library!
Got a small issue

When i'm returning a custom error from the action as following:

export async function action({request, context, params}: ActionArgs) {

    const {
        data,
        errors,
        receivedValues ,
      } = await getValidatedFormData(request, zodResolver(createSpaceInput))

      try {
        const result = context.api.onboarding.setUpSpace.mutate({
            name: data.name
          })
      
        return json({ space: result })
      } catch(e) {
        return json({ 
            errors: {
                root: {
                    message: e.message
                }
            } 
        })
      }
  }

The error can be displayed just fine.
However, when i try to clear the error for example onChange it simply doesn't clear.

 const form = useRemixForm({
    mode: "onSubmit",
    defaultValues: {
      name: "",
    },
    resolver: zodResolver(formSchema),
  });

<RemixForm onSubmit={form.handleSubmit} method={"POST"} onChange={() => {
              console.log('form on change', form.formState.errors)
              form.clearErrors('root')

            }}>

I have also noticed that when I return an error which has the same name as one of the fields:

export async function action({request, context, params}: ActionArgs) {
     ... // rest of the function

        return json({ 
            errors: {
                name: {
                    message: 'some backend error coming from external api'
                }
            } 
        })
  }

It behaves the same way, as in the message is shown just fine, but it can't be cleared up

Any tips?

@AlemTuzlak
Copy link
Contributor

@fenos Hello! The issue you're facing is the fact that when you return the remix errors from the backend they are consumed internally by the hook until they are cleared in the useActionData (eg you submit again). This means that there is no way to remove the errors via form.clearErrors, but this should not indeed be the case but should be cleared. I will make a patch for this when I get the time and this behavior should remove it so this is definitely not the way it should work. Until then I could recommend that you check if the error that comes from the hook is the same as the be one and clear it like that by using useActionData and handling the errors that way

@AlemTuzlak AlemTuzlak added the enhancement New feature or request label Jul 16, 2023
@AlemTuzlak AlemTuzlak self-assigned this Jul 16, 2023
@Centerworx
Copy link

Any progress on this? I have just come across the same issue. If you have a recommend solution I can implement it for you.

@AlemTuzlak
Copy link
Contributor

Any progress on this? I have just come across the same issue. If you have a recommend solution I can implement it for you.

@Centerworx i think the solution is to have a simple setState that is set to true on submit and false on reset and depending on that it consumes the be errors

@Centerworx
Copy link

@AlemTuzlak Working on it. There is an issue around useActionData return the value before submit true is set. Even though it is set to true before calling submit handler. But this may just be test implementation issue.

@Centerworx
Copy link

@AlemTuzlak I have the fix done and tested. I'm having an issue pushing it. Problem with my git.

@xesrevinu
Copy link

xesrevinu commented Aug 24, 2023

Hi, first of all, thanks to @AlemTuzlak for making remix-hook-form. I used usePrevious in the project to get the difference of serverErrors and then merged it, which temporarily solved the problem.

  const errors = data?.errors || emptyErrors
  const [serverErrors, setServerErrors] = React.useState(() => errors)
  const previousServerErrors = usePrevious(serverErrors)

  const formErrors = React.useMemo(() => {
    const keys = Object.keys(serverErrors)
    const prevKeys = previousServerErrors ? Object.keys(previousServerErrors) : []
    const deletedErrorKeys = prevKeys.filter((key) => !keys.includes(key))

    const localErrors = methods.formState.errors as FieldErrors<Output>
    const mergedErrors = mergeErrors<Output>(localErrors, serverErrors, validKeys)

    for (const key of deletedErrorKeys) {
      delete mergedErrors[key]
    }

    return mergedErrors
  }, [methods.formState.errors, previousServerErrors, serverErrors, validKeys])

  React.useEffect(() => {
    if (isSubmitting) {
      setServerErrors(emptyErrors)
    } else {
      // Only update the server errors if the form is not submitting
      setServerErrors(errors)
    }
  }, [errors, isSubmitting])

@piotrkulpinski
Copy link

Is there any progress on this? I just run into the same issue.

@AlemTuzlak
Copy link
Contributor

So this might be potentially fixed with the fact that I moved to using the react-hook-form native "errors" prop, can anyone confirm?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants