Consent

This site uses third party services that need your consent.

Skip to content
Steven Roland
  • Enhancing User Experience with Laravel Precognition

    Laravel Precognition is a powerful feature that allows developers to provide real-time form validation without duplicating validation rules on the frontend. By anticipating the outcome of future HTTP requests, Precognition streamlines the validation process and significantly improves user experience. In this post, we'll explore how to implement Precognition and showcase some practical examples.

    Getting Started with Precognition

    To use Precognition, you first need to add the HandlePrecognitiveRequests middleware to your route:

    use App\Http\Requests\CreateUserRequest;
    use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;
    
    Route::post('/users', function (CreateUserRequest $request) {
        // ...
    })->middleware([HandlePrecognitiveRequests::class]);

    Implementing Live Validation

    Let's look at an example using Vue.js and Inertia. First, install the necessary package:

    npm install laravel-precognition-vue

    Now, create a form component:

    <script setup>
    import { useForm } from 'laravel-precognition-vue';
    const form = useForm('post', '/users', {
        name: '',
        email: '',
        password: '',
    });
    const submit = () => form.submit();
    </script>
    
    <template>
        <form @submit.prevent="submit">
            <input v-model="form.name" @change="form.validate('name')" />
            <div v-if="form.invalid('name')">{{ form.errors.name }}</div>
            <input type="email" v-model="form.email" @change="form.validate('email')" />
            <div v-if="form.invalid('email')">{{ form.errors.email }}</div>
            <input type="password" v-model="form.password" @change="form.validate('password')" />
            <div v-if="form.invalid('password')">{{ form.errors.password }}</div>
            <button :disabled="form.processing">Create User</button>
        </form>
    </template>

    This setup provides real-time validation as the user types, using your server-side validation rules.

    Suggested Usages

    • Multi-step Forms: Use Precognition to validate each step before allowing the user to proceed.

      <script setup>
      import { useForm } from 'laravel-precognition-vue';
      
      const form = useForm('post', '/registration', {
          step: 1,
          name: '',
          email: '',
          // ... other fields
      });
      
      const nextStep = async () => {
          await form.validate(['name', 'email']);
          if (!form.hasErrors()) {
              form.step++;
          }
      };
      </script>
    • Dynamic Form Fields: Validate fields that depend on other inputs.

      <script setup>
      import { useForm, watch } from 'laravel-precognition-vue';
      
      const form = useForm('post', '/order', {
          product_id: null,
          quantity: 1,
      });
      
      watch(() => form.product_id, () => {
          form.validate('quantity');
      });
      </script>
    • Debounced Validation: Implement debounced validation for fields like usernames or email addresses.

      <script setup>
      import { useForm } from 'laravel-precognition-vue';
      import { debounce } from 'lodash';
      
      const form = useForm('post', '/register', {
          username: '',
      });
      
      const debouncedValidate = debounce(() => form.validate('username'), 300);
      </script>
      
      <template>
          <input v-model="form.username" @input="debouncedValidate" />
      </template>
    • File Upload Validation: Use Precognition to validate file uploads before sending the entire form.

      <script setup>
      import { useForm } from 'laravel-precognition-vue';
      
      const form = useForm('post', '/profile', {
          avatar: null,
      });
      
      const validateFile = (event) => {
          form.avatar = event.target.files[0];
          form.validate('avatar');
      };
      </script>
      
      <template>
          <input type="file" @change="validateFile" />
          <div v-if="form.invalid('avatar')">{{ form.errors.avatar }}</div>
      </template>

    Best Practices

    • Keep Backend Validation: Always maintain server-side validation as the ultimate authority.

    • Handle Network Errors: Provide feedback for network issues during validation.

    • Progressive Enhancement: Ensure your forms work without JavaScript as a fallback.

    • Performance Considerations: Be mindful of the number of requests made, especially for high-traffic applications.

    Laravel Precognition offers a powerful way to enhance user experience by providing immediate feedback without sacrificing the security and reliability of server-side validation. By implementing Precognition in your Laravel applications, you can create more responsive and user-friendly forms while maintaining a single source of truth for your validation rules.

    More posts

    Streamlining Code Style with Laravel Pint

    Laravel Pint is a zero-configuration PHP code style fixer for Laravel projects. It offers basic usage for entire projects, targeted formatting for specific files, and inspection of changes. Suggested uses include pre-commit hooks, CI/CD integration, editor integration, and custom configurations. Best practices involve regular use, team adoption, version control of configurations, and gradual implementation for large projects.

    Life as a Sonnet: Madeleine L'Engle's Poetic Wisdom

    Madeleine L'Engle's quote from "A Wrinkle in Time" compares life to writing a sonnet, highlighting the balance between structure and creativity. It emphasizes personal responsibility in shaping our lives within given constraints.