ui icon indicating copy to clipboard operation
ui copied to clipboard

form validate api throws an error and prevents @error event.

Open jimbatamang opened this issue 1 year ago • 7 comments

Environment


  • Operating System: Darwin
  • Node Version: v21.5.0
  • Nuxt Version: -
  • CLI Version: 3.11.1
  • Nitro Version: -
  • Package Manager: unknown
  • Builder: -
  • User Config: -
  • Runtime Modules: -
  • Build Modules: -

Version

v2.13.0

Reproduction

https://stackblitz.com/edit/nuxt-ui-u1sg9t?file=app.vue

Description

While using validate() api, it throws the following error and won't fire the @error event on form.

Form.vue:98 Uncaught (in promise) Error: Form validation failed: [

Expected:

Validate the form, if there is an error should able to listen the error event on form so that I can emit the error to parent component.

Or form.value.validate should return the errors while calling from defineExpose.

Additional context

I'm using the form inside the `<UTabs...> and need to validate the form when user click/switch to different tab. For this, I am validating the form programatically.

Logs

Form.vue:98 Uncaught (in promise) Error: Form validation failed: [
  {
    "path": "project",
    "message": "Please provide project name."
  }
]
    at Proxy.validate (Form.vue:98:15)
    at async Proxy.validate (form.vue:20:5)

jimbatamang avatar Apr 01 '24 23:04 jimbatamang

You can use try...catch... to manually catch errors and solve your problem.

async function validateInsideForm() {
  try {
    await form.value.validate();
  } catch (error) {
    emits('error', error);
  }
}

YIngChenIt avatar Apr 02 '24 02:04 YIngChenIt

You can use try...catch... to manually catch errors and solve your problem.

async function validateInsideForm() {
  try {
    await form.value.validate();
  } catch (error) {
    emits('error', error);
  }
}

Thank you so much for your reply. I think partially yes, try catch will help me to resolve my issue in a patchy way only.

The error is coming as a string. That means, I will have to find the [] part either using regex or replacing and parsing them in to array.

jimbatamang avatar Apr 02 '24 02:04 jimbatamang

您可以使用 try...catch... 手動捕獲錯誤並解決您的問題。

async function validateInsideForm() {
  try {
    await form.value.validate();
  } catch (error) {
    emits('error', error);
  }
}

非常感謝你的回覆。我認為部分是的,嘗試捕獲只會幫助我以零散的方式解決我的問題。

錯誤以字串形式出現。這意味著,我必須[]使用正規表示式或將它們替換並解析為數組來找到該部分。

You are right.

@benjamincanac

Is it necessary for us to trigger emit('error', error) when calling validate, and throw error information in array format, just like validation during submission?

YIngChenIt avatar Apr 02 '24 02:04 YIngChenIt

您可以使用 try...catch... 手動捕獲錯誤並解決您的問題。

async function validateInsideForm() {
  try {
    await form.value.validate();
  } catch (error) {
    emits('error', error);
  }
}

非常感謝你的回覆。我認為部分是的,嘗試捕獲只會幫助我以零散的方式解決我的問題。 錯誤以字串形式出現。這意味著,我必須[]使用正規表示式或將它們替換並解析為數組來找到該部分。

You are right.

@benjamincanac

Is it necessary for us to trigger emit('error', error) when calling validate, and throw error information in array format, just like validation during submission?

I think to make this validate api call usable and unify with other error standards, yes it should return the simple array/object format.

for now, I'm doing this unnecessary steps to resolve this issue (temporary solution)

try {
        await form.value.validate()
    } catch (error) {
        const errorString = error.toString()
        const trimmedErrorString = errorString.replace(/Error: Form validation failed: /, '');
        const errorObject = JSON.parse(trimmedErrorString);
        
        onError(errorObject)
        return
    }

jimbatamang avatar Apr 02 '24 03:04 jimbatamang

Errors are also exposed through the form's api so you can simplify your example with something like this:

try {
  await form.value.validate()
} catch (error) {
  onError(form.value.getErrors())
  return
}

I'll look into including the error array directly into the FormException for simplification.

Is it necessary for us to trigger emit('error', error) when calling validate, and throw error information in array format, just like validation during submission?

I think the default behavior should stay the same for use cases like this:

function submit() {
  const state = await form.value.validate()
  post('/todo', state) // Will only post if the state is valid 
}

What we can do is to add an option to the validate function to emit instead of throwing an error, like this:

function submit() {
  const state = await form.value.validate({ emit: true })
}

romhml avatar Apr 06 '24 10:04 romhml

onError(form.value.getErrors())

Thanks @romhml for your reply.

I like the idea of getting the errors from form's api.

The reason, I was expecting the error responses on validate was because I'm validating the form by parent component and need to know the errors if it fails.

The proposed solution state = await form.value.validate({ emit: true }) seems to be a simple and cleanest solution.

jimbatamang avatar Apr 08 '24 01:04 jimbatamang

After discussing it with @benjamincanac, we'll add the option in the next major version.

romhml avatar Apr 08 '24 15:04 romhml