Populating form values with data coming from an API call #735
Answered
by
sokhengpory
mauserzjeh
asked this question in
Q&A
-
How can I load form values from an API call? ie.: I have a form where I can edit a workspace's details like name etc... When I open the page I make an API call and I would like to fill the form's values from the API call's response. <template>
<Layout>
<form @submit="onSubmit" class="space-y-8 mt-4">
<div class="grid gap-2">
<FormField v-slot="{ componentField, meta }" name="name">
{{ componentField }}
<FormItem v-auto-animate>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="My Workspace" v-bind="componentField"
:invalid="meta.validated && !meta.valid" />
</FormControl>
<FormMessage />
</FormItem>
</FormField>
</div>
<div class="flex gap-2 justify-end">
<Button type="submit" :disabled="isLoading">
<Loader2 v-if="isLoading" class="mr-2 h-4 w-4 animate-spin" />
Save
</Button>
</div>
</form>
</Layout>
</template>
<script setup lang="ts">
import Layout from './Layout.vue';
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Button } from '@/components/ui/button'
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import { toTypedSchema } from '@vee-validate/zod';
import { z } from 'zod';
import { useForm } from 'vee-validate';
import { computed, onMounted, ref } from 'vue';
import { Loader2, Copy } from 'lucide-vue-next';
import { vAutoAnimate } from '@formkit/auto-animate/vue'
import { useWorkspaceStore } from '@/stores/workspace';
import WorkspaceService from '@/api/gen/WorkspaceService';
import { toastError } from '@/components/ui/sonner';
const isLoading = ref(false)
const workspaceStore = useWorkspaceStore()
const currentWorkspaceId = computed(() => workspaceStore.currentWorkspace?.id || '')
onMounted(async () => {
if (currentWorkspaceId.value === '') {
return
}
const resp = await WorkspaceService.getWorkspace({ id: currentWorkspaceId.value })
if (!resp.success) {
toastError(resp.errorMessage)
return
}
console.log(resp.data)
// resp.data contains the data of the workspace
})
const validationSchema = toTypedSchema(z.object({
name: z.string({ message: "Workspace name is required" })
}))
const { handleSubmit, setErrors } = useForm({
validationSchema
})
const onSubmit = handleSubmit(async (values) => {
console.log(values)
})
</script> |
Beta Was this translation helpful? Give feedback.
Answered by
sokhengpory
Aug 30, 2024
Replies: 2 comments 1 reply
-
I ended up doing it this way, please let me know if there is a better solution. <template>
<Layout>
<form @submit="onSubmit" class="space-y-8 mt-4">
<div class="grid gap-2">
<FormField v-slot="{ componentField, meta }" name="name">
<FormItem v-auto-animate>
<FormLabel>Name</FormLabel>
<FormControl>
<Input placeholder="My Workspace" v-bind="componentField"
:invalid="meta.validated && !meta.valid" />
</FormControl>
<FormMessage />
</FormItem>
</FormField>
</div>
<div class="flex gap-2 justify-end">
<Button type="submit" :disabled="isLoading">
<Loader2 v-if="isLoading" class="mr-2 h-4 w-4 animate-spin" />
Save
</Button>
</div>
</form>
</Layout>
</template>
<script setup lang="ts">
import Layout from './Layout.vue';
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Button } from '@/components/ui/button'
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
import { toTypedSchema } from '@vee-validate/zod';
import { z } from 'zod';
import { useForm } from 'vee-validate';
import { computed, onMounted, ref, watch } from 'vue';
import { Loader2, Copy } from 'lucide-vue-next';
import { vAutoAnimate } from '@formkit/auto-animate/vue'
import { useWorkspaceStore } from '@/stores/workspace';
import { toast } from 'vue-sonner';
import WorkspaceService from '@/api/gen/WorkspaceService';
import { toastError } from '@/components/ui/sonner';
const isLoading = ref(false)
const workspaceStore = useWorkspaceStore()
const currentWorkspaceId = computed(() => workspaceStore.currentWorkspace?.id || '')
const validationSchema = toTypedSchema(z.object({
name: z.string({ message: "Workspace name is required" })
}))
const { handleSubmit, setErrors, setFieldValue } = useForm({
validationSchema
})
const onSubmit = handleSubmit(async (values) => {
console.log(values)
})
onMounted(async () => {
if (currentWorkspaceId.value === '') {
return
}
const resp = await WorkspaceService.getWorkspace({ id: currentWorkspaceId.value })
if (!resp.success) {
toastError(resp.errorMessage)
return
}
setFieldValue('name', resp.data.Name) // <-- set the value after receiving it from the API
})
</script> |
Beta Was this translation helpful? Give feedback.
0 replies
-
From the Vee Validate docs setting-initial-values-asynchronously |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
mauserzjeh
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
From the Vee Validate docs setting-initial-values-asynchronously