inertia-laravel icon indicating copy to clipboard operation
inertia-laravel copied to clipboard

Laravel Inertia Form Validation Issue

Open alex-greaves opened this issue 1 year ago • 0 comments
trafficstars

I have the ability to add and update service options. When adding a new service option it doesn't seem to trigger the validation. I have a Create and an Edit component, both of which are just a wrapper with the post route and call the form component.

Create

 <script setup>
     import { useForm } from '@inertiajs/vue3';
     import OptionForm from '@/Components/Service/OptionForm.vue';

     const props = defineProps({
         service: {
             type: Object
         }
     });

     const emit = defineEmits(['complete']);

     const form = useForm({
         name: null,
         type: null,
         help_text: null,
         price: 0,
         price_config: null,
         choices: null
     });

     const submit = () => {
         console.log('submit create', form);
         form.post(--- route ---,
             {onSuccess: (res) => console.log('success', res), onError: (err) => console.log('error', err)}
         )
     }

 </script>

 <template>

     <form @submit.prevent="submit">
         <OptionForm :form="form" :header="'New Service Option'"/>
     </form>
 </template>

Edit

 <script setup>
     import { useForm } from '@inertiajs/vue3';
     import OptionForm from '@/Components/Service/OptionForm.vue';

     const props = defineProps({
         service: {
             type: Object
         },
         option: {
             type: Object
         }
     });

     const emit = defineEmits(['complete']);

     const serviceOptionForm = useForm({
         name: props.option.name,
         type: props.option.type,
         help_text: props.option.help_text,
         price: props.option.price,
         price_config: props.option.price_config,
         choices: props.option.choices
     });

     const submit = () => {
         console.log('submit update', serviceOptionForm);
         serviceOptionForm.patch(
             --- route ---,
             {onSuccess: (res) => console.log('succ', res), onError: (err) => console.log('error', err)}
         )
     }
 </script>

 <template>

     <form @submit.prevent="submit">
         <OptionForm :form="serviceOptionForm" :option="option" :header="'Update Service Option'"/>
     </form>
 </template>

Both of these call the same OptionForm component which has all the form fields etc. They also use the same request on the backend

public function store(StoreServiceOptionRequest $request... public function update(StoreServiceOptionRequest $request...

 class StoreServiceOptionRequest extends FormRequest
 {
     /**
      * Determine if the user is authorized to make this request.
      */
     public function authorize(): bool
     {
         return true;
     }

     /**
      * Get the validation rules that apply to the request.
      *
      * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
      */
     public function rules(): array
     {
         return [
             'name' => 'required|string',
             'type' => 'required|string',
             'help_text' => 'nullable|string',
             'price' => 'nullable',
             'price_config' => 'nullable|string',
         ];
     }
 }

When I submit the create form I get no validation errors, when I submit the edit form I do. Here is a breakdown showing the initial mounting of the blank form object, then submitting, and it returning success. Then mounting the existing object, submitting after removing the name field, and it returning an error.

Screenshot 2024-01-21 at 22 38 38

I did notice that it defaults to an empty string instead of null, so tested with that and it is still incorrectly successful.

Screenshot 2024-01-21 at 22 39 06

For context at the very top-level these exist in modals on the service page

         <v-dialog width="500" v-model="showNewServiceOptionDialog">
             <CreateOption :service="service" @complete="showNewServiceOptionDialog = false"/>
         </v-dialog>

         <v-dialog width="500" v-model="showEditServiceOptionDialog">
             <EditOption :service="service" :option="option" @complete="showEditServiceOptionDialog = false"/>
         </v-dialog>

Stack:

  • Laravel v10.33
  • Breeze v1.26.2
  • Vue v3.2.41
  • Inertia v1.0.0

alex-greaves avatar Jan 22 '24 06:01 alex-greaves