Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

ZackBz's avatar

InertiaJS Partial Reloading Issues

Having bit of an issue when trying to return data back to the view on a partial reload. For some context I have a project that I am using The Movie Database on in which I have a tabbed component where each header is a season. On click of a season tab header, it runs a function:

const form = useForm({
    season: 1, 
    tvId: route().params.id,
})

const submit = (selectedTab) => {
    const index = selectedTab.tab.index
    const currentTab = props.tvDetails.data.seasons[index]
    form.season = currentTab.season_number
    form.post(route('episodes'), {
        only: ['tvEpisodes'],
        preserveState: true,
        preserveScroll: true,
    })
}

Then in my controller im doing something like this:

public function getTvEpisodes(Request $request)
    {
        $key = env("TMDB_API_KEY");

        $season = $request->input('season');
        $tvId = $request->input('tvId');

        $tvEpisodes = Http::get("https://api.themoviedb.org/3/tv/{$tvId}/season/{$season}?api_key={$key}&language=en-US")->json();
        return back()->with(['tvEpisodes' => fn() => TvEpisodeResource::make($tvEpisodes)]);
    }

Now the issue comes from the closure, "Serialization of 'Closure' not allowed". I know that I must rewrite my return statement but how? According to InertiaJS docs on partial reloading, I should be doing this correctly. Any advice on how to resolve this?

0 likes
5 replies
MohamedTammam's avatar

No, that isn't the right way.

When you redirect back you don't do it with partial reload. And you shouldn't add a lot of data in with because it store this data in the session for the next response.

The partial reload should be while returning Inertia response.

MohamedTammam's avatar

@ZackBz Depends on your logic. If you need to redirect back then just use.

return back();

And the previous route should handle the partial reload if needed

Or use Inertia::render if you don't need to redirect the user back.

eggplantSword's avatar
Level 9

If you want to use Partial Relaods you have to do it like this: in the same method you return Inertia::render on your page you add the extra data. Using Inertia::lazy means that this won't be done until you explicitly ask for it from the front.

$key = env("TMDB_API_KEY");

$season = $request->input('season');
$tvId = $request->input('tvId');

return Inertia::render('YourComponent', [
     'tvEpisodes' => Inertia::lazy(fn() => Http::get("https://api.themoviedb.org/3/tv/{$tvId}/season/{$season}?api_key={$key}&language=en-US")->json()),
])

Now in your vue file all you can change it to this or also you can use a reload

this.$inertia.get(
                `YourRoute`,
                {
					//you can send your data in here 
					season: this.form.season,
					tvId: this.form.tvId
				},
                {
                    replace: true,
                    preserveState: true,
                    preserveScroll: true,
                    only: ['tvEpisodes'],
                }
            );

Check out the docs https://inertiajs.com/partial-reloads

1 like
ZackBz's avatar

@msslgomez I was able to resolve the issue with,

Controllers: getTvDetails is my initial render of the page, and I lazy load tv Episodes.

 public function getTvDetails($id)
    {
        $key = env("TMDB_API_KEY");
        $data = Http::get("https://api.themoviedb.org/3/tv/{$id}?api_key={$key}&language=en-US")->json();

        return Inertia::render('TV/Detail', [
            "tvDetails" => TvDetailResource::make($data),
            'tvEpisodes' => Inertia::lazy(fn() => App::call([$this, 'lazyLoadTvEpisodes'])),
        ]);
    }

Then on click of a tab header:

public function lazyLoadTvEpisodes(Request $request)
    {
        $key = env("TMDB_API_KEY");

        $season = $request->input('season');
        $tvId = $request->input('tvId');

        $tvEpisodes = Http::get("https://api.themoviedb.org/3/tv/{$tvId}/season/{$season}?api_key={$key}&language=en-US")->json();

        return TvEpisodeResource::make($tvEpisodes);
    }
}

and my form:

const form = useForm({
    season: 1, 
    tvId: route().params.id,
})
const submit = (selectedTab) => {
  // console.log(selectedTab);
  const index = selectedTab.tab.index
  const currentTab = props.tvDetails.data.seasons[index]
  console.log(currentTab);
  form.season = currentTab.season_number
  router.reload({
    data: form.data(),
    only: ['tvEpisodes'],
    preserveState: true,
    preserveScroll: true,
    onSuccess() {
      console.log(props.tvEpisodes);
    },
  })
}

Thanks for the help!

Please or to participate in this conversation.