inertiajs / inertia-laravel

The Laravel adapter for Inertia.js.
https://inertiajs.com
MIT License
2.01k stars 224 forks source link

Laravel Inertia Form Validation Issue #580

Open alex-greaves opened 7 months ago

alex-greaves commented 7 months ago

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: