Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validation errors are not passed as props #52

Closed
iamohd-zz opened this issue Aug 15, 2019 · 2 comments
Closed

Validation errors are not passed as props #52

iamohd-zz opened this issue Aug 15, 2019 · 2 comments

Comments

@iamohd-zz
Copy link

I am doing a simple login form, using the existing login logic of LoginController@login

The request hits the controller successfully, but when there is validation failure, the response is always missing props. In this case I am not able to get the validation errors.

response sample:

{component: "front/auth/login", props: [], url: "/login", version: null}
component: "front/auth/login"
props: []
url: "/login"
version: null

this is my vue code

export default {
    data() {
        return {
            form: {
                email: null,
                password: null,
                remember: 1
            }
        }
    },

    methods: {
        submit() {
             this.$inertia.post('/login', this.form).then((response) => {
             console.log(this.$inertia.page);
         });
      }
    }
}

and the html login form is very simple:

<form class="flex flex-col w-full bg-white rounded-lg shadow p-8 mt-10" @submit.prevent="submit">
   <label class="form-group">
   <span class="form-label">Email</span>
   <input type="email" name="email" class="form-input" tabindex="1" v-model="form.email" autofocus>
   </label>
   <label class="form-group">
   <span class="form-label">
   <span class="form-label">
   Password
   <a href="#" class="float-right text-xs text-blue-500 hover:text-blue-600 hover:underline">Forgot Password?</a>
   </span>
   </span>
   <input type="password" name="password" class="form-input" tabindex="2" v-model="form.password">
   </label>
   <button type="submit" class="btn btn-blue btn-block">Login</button>
</form>

Also I am using the latest version of each package:

inertia 0.1.3
inertia-vue 0.1.1
inertia-laravel 0.1.0

@bonzai
Copy link
Contributor

bonzai commented Aug 15, 2019

Inertia doesn't automatically include validation errors, but you can use Inertia::share() method in your service provider to add them to your response:

Inertia::share([
    'errors' => function () {
        return Session::get('errors')
            ? Session::get('errors')->getBag('default')->getMessages()
            : (object) [];
]);

@reinink
Copy link
Member

reinink commented Aug 15, 2019

Hello @mohd-isa! Thanks for your interest in Inertia. I think you will find this response I gave on Twitter helpful regarding error handling. 👍

Question:

So how do you handle a 422 response in Inertia when you're posting data? Do I need to add a custom header so inertia knows how to catch failed validation? Thanks for your feedback

Answer:

Great question! The trick is to not think of Inertia like a client-side framework, but rather a server-side framework.

So, with a client-side framework you'd catch the errors client-side, which would include some JSON error messages, and you'd update your view to show them.

With Inertia, you handle it like a server-side form submission.

You submit your form (POST). If there are errors, your server-side framework redirects back (GET) to your form page, and includes the errors in the session.

Then, you need to send those error messages to the view. Laravel automatically makes them available within the Blade views as $errors. However, we're not using Blade. So, we need to include the errors with our Inertia response, so they can be passed back to our page as a prop.

In my apps, I do this automatically on every request. If there are errors in the session, I include them as an errors prop.

You can see this here: https://github.com/inertiajs/pingcrm/blob/master/app/Providers/AppServiceProvider.php#L48-L50

This makes it work a lot like Blade, which always has access to the $errors object.

Your form page component has now received updated props, which include the errors prop, also accessible as $page.errors in Vue.js. Since Vue.js/React are reactive, the page will automatically update to show the form errors.

See here: https://github.com/inertiajs/pingcrm/blob/master/resources/js/Pages/Users/Create.vue#L10-L14

So, in summary:

  1. Submit form via $inertia.post
  2. If errors, server-side redirect back (GET) to form page
  3. The errors are saved in the session
  4. Errors are passed as shared data to Vue.js
  5. Your page displays those errors, which happens reactively

This certainly requires a shift in thinking about things, but this whole approach works REALLY well.

It's just like how we used to do classic server-side form submissions. Except it's way nicer than that, since you're not reloading the whole page, or rehydrating form input.

@reinink reinink closed this as completed Aug 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants