You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Something that new users to Inertia keep bumping into is the fact that the onSuccess callback is called even when validation errors are present (#252, #325, #314, inertiajs/inertia-laravel#172, inertiajs/inertia-laravel#184). This is because, in an Inertia app, you never receive a 422 response. Instead, when you submit a form, if there are validation errors, you get redirected back, server-side, to the form page you're currently on, and the validation errors are then available in the errors prop. This redirect results in a 200 response on the form page, not a 422 response. This is exactly like standard full page form submissions with server-side rendering. Meaning, even if there are validation errors, Inertia still calls the onSuccess callback...because it was a successful response. There just happens to also be validation errors present in the props.
This is generally fine, since our forms reactively update based on the errors prop and display the validation errors. However, there are edge cases where you actually want to do something after a response has finished, in the event that no validation errors have occurred. For example, consider an update profile form, which has a password input. It's very common to want to clear the password form on a successful form submission. The currently recommended way to do this is via the onSuccess callback, checking to see if any errors are present.
And while this works (and technically makes sense), it's not the most ergonomic API. It would be nicer if Inertia could somehow detect if the response included validation errors, and only call the onSuccess callback if no errors are present. For example:
We could even add a new onError callback, should you want to do some type of form cleanup.
this.$inertia.post('/profile',this.form,{onError: errors=>{/* do something */},})
Resolving errors
The hard part here is knowing when a response includes validation errors. Remember, there is no 422 response. One solution is to look for the presence of an errors prop. In Laravel, it's totally common to have a global errors prop (in fact, the Laravel adapter automatically sets this), however, other server-side frameworks may not work this way. To solve this, we would add a new resolveErrors callback, where you could set this for your own application.
In the event that the errors object that is returned from this function contains any errors, Inertia would consider it a "validation error response", and would call onError instead of onSuccess. This errors object would also be passed to the new onError callback.
The resolveErrors callback would be optional, and the default implementation would simply look for the root level errors prop.
Global event
I think it would also make sense to add a global error event in addition to the onError callback. Unfortunately, we already have a global error event. I propose that we rename the current error event to exception, and then use the error event for validation errors.
This is probably a good change either way, since the current error only event fires on unexpected XHR errors, such as network interruptions, and for errors generated in the resolveComponent() callback. It does not fire for XHR requests that receive 400 and 500 level responses, or for non-Inertia responses, as these situations are handled in other ways by Inertia. Meaning, these are "exceptional" events.
Link component
We will need to update the <inertia-link> components (all four adapters) add add the new onError callback.
This discussion was converted from issue #356 on December 19, 2020 17:30.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Something that new users to Inertia keep bumping into is the fact that the
onSuccess
callback is called even when validation errors are present (#252, #325, #314, inertiajs/inertia-laravel#172, inertiajs/inertia-laravel#184). This is because, in an Inertia app, you never receive a422
response. Instead, when you submit a form, if there are validation errors, you get redirected back, server-side, to the form page you're currently on, and the validation errors are then available in theerrors
prop. This redirect results in a200
response on the form page, not a422
response. This is exactly like standard full page form submissions with server-side rendering. Meaning, even if there are validation errors, Inertia still calls theonSuccess
callback...because it was a successful response. There just happens to also be validation errors present in the props.This is generally fine, since our forms reactively update based on the
errors
prop and display the validation errors. However, there are edge cases where you actually want to do something after a response has finished, in the event that no validation errors have occurred. For example, consider an update profile form, which has a password input. It's very common to want to clear the password form on a successful form submission. The currently recommended way to do this is via theonSuccess
callback, checking to see if any errors are present.A better API
And while this works (and technically makes sense), it's not the most ergonomic API. It would be nicer if Inertia could somehow detect if the response included validation errors, and only call the
onSuccess
callback if no errors are present. For example:We could even add a new
onError
callback, should you want to do some type of form cleanup.Resolving errors
The hard part here is knowing when a response includes validation errors. Remember, there is no 422 response. One solution is to look for the presence of an
errors
prop. In Laravel, it's totally common to have a globalerrors
prop (in fact, the Laravel adapter automatically sets this), however, other server-side frameworks may not work this way. To solve this, we would add a newresolveErrors
callback, where you could set this for your own application.In the event that the
errors
object that is returned from this function contains any errors, Inertia would consider it a "validation error response", and would callonError
instead ofonSuccess
. This errors object would also be passed to the newonError
callback.The
resolveErrors
callback would be optional, and the default implementation would simply look for the root levelerrors
prop.Global event
I think it would also make sense to add a global
error
event in addition to theonError
callback. Unfortunately, we already have a globalerror
event. I propose that we rename the currenterror
event toexception
, and then use theerror
event for validation errors.This is probably a good change either way, since the current
error
only event fires on unexpected XHR errors, such as network interruptions, and for errors generated in theresolveComponent()
callback. It does not fire for XHR requests that receive 400 and 500 level responses, or for non-Inertia responses, as these situations are handled in other ways by Inertia. Meaning, these are "exceptional" events.Link component
We will need to update the
<inertia-link>
components (all four adapters) add add the newonError
callback.Beta Was this translation helpful? Give feedback.
All reactions