Show the code in the controller please.
`patch` results in full page refresh when request validation fails. How does Inertia expect one to use `patch` in nested React components with partial reload?
I have a component that enables the user to modify a record in the database. Regardless of if I use { only: ['account'], preserveUrl: true, preserveState: true, preserveScroll: true }—the page fully refreshes when a validation exception is thrown which results in my component failing to inherit the errors bag.
Does Inertia expect me to prefer Axios for these component-level patch calls?
Edit Correction to this post: A full page refresh is occurring on all requests—even successful ones.
I was under the impression it was only happening on validation failure.
Happy to.
I excluded it in my opening post because the Request is throwing a validation error before the controller method is executed.
// Controller
public function update(UpdateFinancialAccountsRequest $request, FinancialAccount $account)
{
$account->update($request->validated());
return redirect()->intended(url()->previous(), 303);
}
// Request rules
public function rules(Request $request): array
{
return [
'name' => [
'min:1',
'max:255',
Rule::unique('financial_accounts', 'name')
->where('user_id', $request->user()->id),
],
'current_balance' => [
'numeric',
'nullable',
Rule::when(
$request->input('type') === FinancialAccountType::Cash->value,
['gte:0']
),
],
'type' => [Rule::in(FinancialAccountType::supported())],
];
}
In the scenario outlined in my opening post, I am intentionally submitting a value for name that breaks the unique rule. It's when the validation error is thrown that the full page refresh is triggered.
Sorry, I was incorrect. A full page refresh is occurring on all requests—even successful ones.
I was under the impression it was only happening on validation failure.
How are you sending the request.
This is not what the intended() method is for:
return redirect()->intended(url()->previous(), 303);
That method is for redirecting the user to the URL that they were trying to access when an auth check failed and they were redirected to a login page. It's only appropriate to use it at the end of a successful login.
Here, you should just redirect back, or you can get incorrect behavior in some situations.
return back();
As for the full page reload, there could be many causes. Please show the front-end request code and the form page controller method.
I'm using patch from useForm to send the request.
Regarding the controller return, back(303) is what I had implemented originally.
I'll provide the full code when I get home.
Here's the code I promised. The only thing I can imagine is that this is somehow due to the fact that I am calling the patch from a subcomponent. I'm at a loss for what is triggering the page reload. It occurs regardless of if the request is abandoned due to a validation error or if the request completes successfully.
// Controller
public function update(UpdateFinancialAccountsRequest $request, FinancialAccount $account)
{
$account->update($request->validated());
return back();
}
// Page component
export default function Index({ financialAccounts }: { financialAccounts: FinancialAccountModel[] }) {
return (
<AppLayout breadcrumbs={breadcrumbs}>
<Head title="Dashboard" />
<div className="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
{financialAccounts?.map((acc) =>
<FinancialAccountSummary key={acc.id} account={acc} patchOptions={{ only: ['financialAccounts'] }} />
)}
</div>
...
// FinancialAccountSummary relevant content
const { data, setData, processing, errors, reset, patch } = useForm(formDefaults);
<form
onSubmit={() => {
if (data.name.length === 0) return;
patch(route('financial-accounts.update', { account: account.id }), {
...patchOptions,
onSuccess: () => {
console.log('success?');
},
onError: (err) => {
console.log('error?', err);
},
});
}}
>
@jimofthestoneage Show the form page controller.
the page fully refreshes when a validation exception is thrown which results in my component failing to inherit the errors bag.
When you say the page fully refreshes, what exactly happens?
A validation exception is necessary for the form helper to work correctly. When Laravel throws a validation exception, it also passes validation errors in the response. When the form helper receives a 422 response, it reads the error messages from the response, hydrates the errors variable in the useForm hook, and sets processing to false. If there was no validation exception, you wouldn't get any error messages.
@jussimannisto by "refresh" I mean it's as if the refresh button in the browser was clicked — the page completely reloads. Network history is lost in Dev tools, console log history is cleared, the place is fully reloadef. The interesting thing, however, is that errors is populated with the validation error.
If I can get to the root of why and when inertia chooses to truly reload the page vs when it chooses to populate the page props only, I imagine I can then get to the root of this issue.
@jimofthestoneage This probably isn’t the answer to your question, but the inertia preserveState option may be helpful. Also, remember to use <Link> tags rather than anchor tags on your pages, otherwise you’ll get a full page refresh.
Show the form page controller, i.e. the endpoint that returns the Inertia::render() call.
The reload could be caused by something on the backend, e.g. in the controller or a middleware.
@JussiMannisto back() in the update() controller sends the user to:
public function index(Request $request)
{
if ($request->user()->cannot('viewAny', FinancialAccount::class)) {
abort(403);
}
return Inertia::render('financial-account/index', [
'financialAccounts' => $request->user()->financialAccounts,
]);
}
It always comes down to the basics, doesn't it? I was missing e.preventDefault() in my form onSubmit 😂
Please or to participate in this conversation.