form.value.setErrors is undefined
Environment
- Operating System: Darwin
- Node Version: v20.14.0
- Nuxt Version: 3.12.2
- CLI Version: 3.12.0
- Nitro Version: 2.9.6
- Package Manager: [email protected]
- Builder: -
- User Config: devtools, extends, modules, runtimeConfig, image, nitro, ui, formkit, tailwindcss, i18n, eslint
- Runtime Modules: @nuxt/[email protected], @nuxt/[email protected], @nuxt/[email protected], @nuxt/[email protected], @pinia/[email protected], @nuxtjs/[email protected], @formkit/[email protected], @vueuse/[email protected], @nuxtjs/[email protected]
- Build Modules: -
Version
3.12.2
Reproduction
I try to follow this example on docs:
<script setup lang="ts">
import type { FormError, FormSubmitEvent } from '#ui/types'
const state = reactive({
email: undefined,
password: undefined
})
const form = ref()
async function onSubmit (event: FormSubmitEvent<any>) {
form.value.clear()
try {
const response = await $fetch('...')
// ...
} catch (err) {
if (err.statusCode === 422) {
form.value.setErrors(err.data.errors.map((err) => ({
// Map validation errors to { path: string, message: string }
message: err.message,
path: err.path,
})))
}
}
}
</script>
<template>
<UForm ref="form" :state="state" @submit="onSubmit">
<UFormGroup label="Email" name="email">
<UInput v-model="state.email" />
</UFormGroup>
<UFormGroup label="Password" name="password">
<UInput v-model="state.password" type="password" />
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>
Description
Is there anything is out of dated compare to the latest version of nuxt?
Additional context
Logs
No response
Hello! It looks like you're trying to use the function before the component is mounted:
form.value?.setErrors(/* ... */); // This will be undefined since the component is not mounted
onMounted(() => {
form.value.setErrors(/* ... */); // This will be defined
});
See: https://vuejs.org/guide/essentials/template-refs.html#accessing-the-refs
The onSubmit function is called after the component is mounted
Can you send me a reproduction using Stackblitz so I can have a look? I can't reproduce the issue from the documentation's example
hi, I run in the same problem. do your response have a path? My solution was to set it manually
const swwError = ref(false); //somethingWentWrongError
const form = ref();
const onSubmit = async (event) => {
try {
const data = await authStore.create(event.data);
router.push("/");
} catch (error) {
//email exists already
if (error.response.status === 422) {
form.value.setErrors([
{
message: error.response.data.message,
path: "email",
},
]);
} else {
// For all other errors, a standard error message is displayed at the top of the form
swwError.value = true;
}
}
```
This issue is stale because it has been open for 30 days with no activity.
@hckhanh , did you find a solution for this? I am encountering the same issue
@romhml , is there any chance this can be re-opened? I can provide my code, although is basically the same problem that @hckhanh encountered. Thank you
Is this on v2? Can you send me a reproduction using stackblitz or codesandbox? I can check it out
I can't find a way to reproduce it from the original example: https://stackblitz.com/edit/nuxt-ui-vcf3cr5i?file=app.vue
Thank you for replying @romhml . I will try to recreate it. This is my stack:
- Operating System:
Darwin - Node Version:
v22.13.0 - Nuxt Version:
3.15.4 - CLI Version:
3.21.1 - Nitro Version:
2.10.4 - Package Manager:
[email protected] - Builder:
- - User Config:
devtools,extends,runtimeConfig,css,build,modules,piniaPluginPersistedstate,googleFonts,colorMode,site,robots,gtag,routeRules,compatibilityDate - Runtime Modules:
@nuxtjs/[email protected],@nuxt/[email protected],@vueuse/[email protected],@pinia/[email protected],pinia-plugin-persistedstate/[email protected],@nuxt/[email protected],@nuxt/[email protected],[email protected],@nuxtjs/[email protected],@nuxtjs/[email protected],@nuxt/[email protected] - Build Modules:
-
While I set up the stackblitz, I will share a snippet of my code:
<script setup lang="ts">
import * as v from 'valibot'
import type { Form, FormSubmitEvent } from '#ui/types'
// import { isEmailAvailable } from '~/api/user'
const PROMPT_MAX_CHARACTERS = 800
const createStorySchema = v.objectAsync({
email: v.optionalAsync(
v.pipeAsync(
v.string(),
v.trim(),
v.email('Please enter a valid email'),
// v.checkAsync(isEmailAvailable, 'This email is already in use')
)
),
prompt: v.pipe(v.string(), v.maxLength(PROMPT_MAX_CHARACTERS)),
})
type CreateStorySchema = v.InferOutput<typeof createStorySchema>
const form = ref<Form<CreateStorySchema>>()
const state = reactive({
email: undefined,
prompt: '',
})
const remainingCharacters = computed(() => {
return PROMPT_MAX_CHARACTERS - state.prompt.length
})
const doSomething = (data: CreateStorySchema) => {
// Do something
console.log('data', data)
return {
success: false,
errors: [{
path: 'email',
message: 'This is an error message',
}]
}
}
const onSubmit = async (event: FormSubmitEvent<CreateStorySchema>) => {
form.value!.clear()
// Attempt to create the story
const result = doSomething(event.data)
if (result.success) {
// Do something
} else {
if (form.value && result.errors) {
// It will never enter here...
form.value.setErrors(result.errors)
}
}
}
</script>
<template>
<UForm
ref="form"
:schema="v.safeParserAsync(createStorySchema, { abortEarly: true })"
:state="state"
:validate-on="[ 'submit', 'blur' ]"
@submit="onSubmit"
>
<UFormGroup label="Email address" name="email" required>
<UInput
v-model.trim="state.email"
placeholder="Enter your email address"
type="email"
/>
</UFormGroup>
<UFormGroup
label="Label"
description="Description"
name="prompt"
required
:help="`${remainingCharacters}/${PROMPT_MAX_CHARACTERS} characters left`"
eager-validation
>
<UTextarea
v-model.trim="state.prompt"
placeholder="For example: This is my prompt"
:rows="5"
padded
resize
:maxlength="PROMPT_MAX_CHARACTERS"
/>
</UFormGroup>
<UButton type="submit">
Submit
</UButton>
</UForm>
</template>