Skip to content
On this page

Validation

How it works

Validation in Spire means Frontend-Validation through Serverside-Validation. This works by using Laravels (default) Features when using FormRequests and, for realtime validation, Laravels Precognition Feature.

Validation is mostly powered by middleware, with an additional useFormState composable that aids in propagating validation errors to components (like Inputs and Selects).

If Laravel encounters a Validation Error, it will throw a ValidationException. Spire will catch this Exception and transform the response accordingly.

The catchValidationException Middleware will handle setting those errors, while the resetValidationErrors Middleware will reset those errors on each new request.

Components can then use the useFormState composable to check if a given field on a given entity currently has a validation error.

TIP

Validation is basically "free" if you adhere to Spire's structure. It's working by default.

Using it in Components

If you're developing a Component that needs to check for validation errors on a certain field, you can use the hasErrorForField() and getErrorForField() methods on useFormState() composable.

This is an Example of how a Input might do it:

vue
<script setup lang="ts">
defineProps<{
    field?: FormStateField
}>()

const { hasErrorForField, getErrorForField } = useFormState()
</script>

<template>
    <div
        v-if="field && hasErrorForField(field)"
        class="bg-error-500/90 px-2 py-1.5 rounded-lg text-error-50 text-sm"
    >
        <ul>
            <li
                v-for="error in getErrorForField(field)"
                :key="error"
            >
                {{ error }}
            </li>
        </ul>
    </div>
</template>

INFO

Validations can have multiple entries as to what failed, like "required" aswell as "email not correct". This is why getErrorForField will return an array of error messages.

Handling multiple FormStates

We need to pass the Entity (Model) name to our field in dot-notation to differentiate between different requests.

So if you want to handle the field last_name for a customer you would pass customer.last_name into the field.

This is done to be able to handle multiple different FormStates on each page whilst having the same key names. Think street for either customer or location.

INFO

You can also pass in arrays of field names. This is useful for helper Components where you want to display multiple fields at the same place, like having errors for both zipcode and city on a whole row instead of under their inputs.

Realtime Validation

Using Laravel Precognition we can also easily do realtime validation without executing our controller actions on a success.

You can do this in Spire by using the validateAction() helper.

ts
const { createCustomerAction } = useCustomerActions()
const { create, loading } = allCustomersAction()

const { validate } = validateAction(create, {
    only: ["first_name", "last_name"]
})

You may now call validate(customer) by either adding it directly to your Form by using @keyup or @change events, or by using a watcher on your entity object.