inertia
inertia copied to clipboard
Do not NULL lazyloaded props when redirecting back to the same page
Discussed in https://github.com/inertiajs/inertia/discussions/1628
Originally posted by lpeterke July 31, 2023
Imagine a "Home" page that displays a long list of items, which are loaded using Inertia::lazy().
The "Home" page might also have a child component that sends a simple POST, for example "Subscribe to our newsletter". After the action is performed, the NewsletterController simply redirects using return redirect()->back().
Inertia will then NULL all page props that utilize Inertia::lazy(). However, this feels rather buggy, as we are still on the same page component and nothing should tamper with the lazyloaded props, until a new reload is triggered from code.
Previous discussion: https://github.com/inertiajs/inertia/issues/863
I also require this functionality. I have a modal form that lazy fetches properties before opening, but when redirecting back on a validation form error in Laravel, those properties are seemingly cleared, causing the modal to close and re-fetch those properties. Desired behavior would be to keep these lazy properties around
I agree. I have the same issue with building a Stripe billing portal. Historical Invoices & Payment methods are on LazyLoad using the OnMounted() method to speed everything up as they are time-consuming. When using return back(0 they should persist or, at the very least, be able to reload them. Any workaround?
I haven't implemented a workaround yet. Probably would be a mixin for Vue that manages copies of the lazy props:
- Have an Array "lazy_props" with all page Prop names that are lazyloaded.
- Programmatically register watchers for all values in "lazy_props"
- Have the watchers copy value changes into data attributes
- Provide computed properties that you would use instead of accessing the lazyloaded props directly
Hi guys.
I've found a workaround that I have been able to implement (I only use lazy loading on one section of my app). There might be a better workaround as I am only new to programming. But it might help some others or the project team. If anyone sees any issue with it, please don't hesitate to let me know.
Controller.php
public function updatePaymentMethod(Request $request)
{
auth()->user()->currentTeam->updateDefaultPaymentMethod($request->get('pm_id'));
return back(303)
->with([
'message' => 'Your default payment method was updated',
'type' => 'success',
'title' => 'Success',
'reload' => true,
]);
}
HandleInertiaRequests.php
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'flash' => function () use ($request) {
return [
'message' => fn() => $request->session()->get('message'),
'type' => fn() => $request->session()->get('type'),
'title' => fn() => $request->session()->get('title'),
];
},
'reload' => function () use ($request) {
return fn() => $request->session()->get('reload');
}
], [
'shouldInterpolate' => true,
]);
}
Vue Component (i.e. Show.vue) using Vue3 Composition API
// Lazy Load Initial Props
onMounted(() => {
router.reload({ only: ['historicalInvoices'] });
})
// Set-up Inertia Page Object to Get Shared Data
const page = usePage();
// Watch for set Reload prop. If True Partial lazy Load Reload.
watch(() => page.props.reload,
() => {
console.log(page.props.reload);
if (page.props.reload) {
router.reload({ only: ['historicalInvoices'] });
}
}
)
I found that the key items were:
- Using the getter watch source (if that's the correct terminology) as outlined in the vue docs here
- Setting
'shouldInterpolate' => true,in the HandleInertiaRequests <= I found this on a forum and couldn't find it in the inertia or laravel docs. TBH, I don't know what it does, but it allowed multiple renders when doing multiple calls. I.e. deleting two separate payment methods (very useful for the flash messages also).
Anyone with a workaround for this? Having the same issue here using React. The quick fix was not use the lazy anymore :'(
Hey all. It seems this is more of a feature request. If you want, you can always attempt a PR. Thanks.