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

soleh's avatar
Level 1

Inertia::render not working, giving error this.resolveComponent is not a function. Any Ideas how to resolve it?

Hi Everyone, I am new to Laravel, i started learning it a couple of weeks back. To get a practical hand-on i decided to create a small project. A Project management app, where users can create a project, add tasks set status, add comments, assign it to others users. I created a Laravel Breeze application with Inertia and React. Now I created a ProjectController, a ProjectResource and Project Model.

Now, i created a route "project.index" route, where I render all the projects in tabular format. Till now, everything is fine. Now i want to implement an Excel like filter functionality, where a user clicks on any column, it will display all the available values and when a user click on few options then hit apply, the table should update accordingly.

I created a post route "api/project/get/filter-values". where i return all unique values based on the column key, based on this response, i render the values in the column drop down.

Now to have an apply feature, i created another post oute "api/project/apply/filter", where i pass payload of {key:columnName, filter_items: an array of values selected by users}. Based on this payload i generate a query and return Inertia view same as "project.index" but with the updated projects.

Now, i get following error, in network section, i get the proper response, with the updated props, however in console i get the error

@inertiajs_inertia.js?v=de0c108c:1565 Uncaught (in promise) TypeError: this.resolveComponent is not a function at n2.setPage (@inertiajs_inertia.js?v=de0c108c:1565:37) at @inertiajs_inertia.j…v=de0c108c:1532:111 XMLHttpRequest.send (async) handleApplyFilter @ Index.jsx:33 handleApplyFilter @ TableHead.jsx:14 Show 24 more frames

Here is my web.php file

0 likes
13 replies
gych's avatar

Can you share the code where you're using resolveComponent

Are you using axios request to reach the api endpoints or are you using Inertia with useForm ?

soleh's avatar
Level 1

@gych i am using Inertia.post method to reach to API endpoint, Here is my "Project.index" component

import Table from "@/Components/Table";
import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout";
import { Inertia } from "@inertiajs/inertia";
import { Head, Link, router } from "@inertiajs/react";
import axios from "axios";
import { useEffect } from "react";

export default function Index({ auth, projects }) {
  let columnConfig = [
    {
      name: "Name",
      key: "name",
    },
    {
      name: "Description",
      key: "description",
    },
    {
      name: "Status",
      key: "status",
    },
    {
      name: "Priority",
      key: "priority",
    },
    {
      name: "Created By",
      key: "created_by",
    },
  ];

  const handleApplyFilter = async (filter_items)=>{
    Inertia.post(route('project.filter'),{filter_items})
  }

  return (
    <AuthenticatedLayout
      user={auth.user}
      header={
        <div className="flex justify-between items-center">
          <h2 className="font-semibold text-xl leading-tight">Projects</h2>
          <Link
            href={route("project.index")}
            className="bg-emerald-500 py-1 px-3 text-white rounded shadow transition-all hover:bg-emerald-600"
          >
            Add new
          </Link>
        </div>
      }
    >
      <Head title="Projects" />
      <div className="py-12">
        <div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
          <div className="bg-white overflow-hidden shadow-sm sm:rounded-lg">
            <Table onApplyFilter={handleApplyFilter} columnConfig={columnConfig} data={projects.data} links={projects.meta.links}></Table>
          </div>
        </div>
      </div>
    </AuthenticatedLayout>
  );
}

Here Table is a simple component to render table header and table body based on the column config and data passed

jotricky's avatar

I ever did this before, using the same tech stacks. The way I did it, was that I prepopulated the filterable values in every columns, then return to inertia along with the view. That way, I didn't need to create a separate API endpoints.

In the view, I'm using those prepopulated values and create a form with it, adding a button to filter. Whenever user clicks on the button, a form get will be called on the same method in the same controller. The filter parameters will be applied as query string.

The controller then will check on the passed filter parameters, and regenerate the model data based on the received parameters. Then it will again return an inertia view, with query strings provided.

soleh's avatar
Level 1

@jotricky yes, query strings seems to be a good option however imagine passing 100 values for like 3 columns in query string, the URL will be too long and unreadable. Here is my web.php file

<?php

use App\Http\Controllers\ProfileController;
use App\Http\Controllers\ProjectController;
use Illuminate\Foundation\Application;
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;


Route::get('/', function () {
    return Inertia::render('Dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');

Route::middleware('auth')->group(function () {
    Route::post('api/project/apply/filter', [ProjectController::class, 'apply_filter'])->name('project.filter');
    Route::resource('project', ProjectController::class);
    Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
    Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
    Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
    Route::post('api/project/get/filter-values', [ProjectController::class, 'get_filter_values']);

});

require __DIR__.'/auth.php';

See here i have "project.index" route and then i also have "project.filter" route, index route works fine bit for filter route when i return as follows

public function apply_filter(Request $request) {
        $filterItems = $request->input('filter_items');

        // Assuming 'name' is the attribute you want to filter by
        $filteredProjects = Project::whereIn('name', $filterItems)->paginate(10)->onEachSide(1);
        return inertia('Project/Index', [
            "projects" => ProjectResource::collection($filteredProjects),
        ]);

i get this.resolveComponent is not a function in the console and the view also doesn't update however in the network section i get a proper response with the proper props. Is is because for Index route i am also resolving same component, can't two routes resolve same component but with different data in Laravel??

gych's avatar

Its strange that you get the error about resolveComponent, can you share app.jsx file

soleh's avatar
Level 1

@gych This is app.jsx


import './bootstrap';
import '../css/app.css';

import { createRoot } from 'react-dom/client';
import { createInertiaApp } from '@inertiajs/react';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';

const appName = import.meta.env.VITE_APP_NAME || 'Laravel';

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => resolvePageComponent(`./Pages/${name}.jsx`, import.meta.glob('./Pages/**/*.jsx')),
    setup({ el, App, props }) {
        const root = createRoot(el);

        root.render(<App {...props} />);
    },
    progress: {
        color: '#4B5563',
    },
});

Furthermore i also tried to return back()->with([ "projects"=>$filtered_projects ])

That didn't work also, i got 409 conflict error and the entire app reloaded

gych's avatar

@soleh That looks good, try to use router.post instead of Inertia.post

  const handleApplyFilter = async (filter_items) => {
    router.post(route('project.filter'), {filter_items});
  }
3 likes
soleh's avatar
Level 1

@gych Yes, finally it is working. Can you please tell me what is difference between router.post and Inertia.post and when to use router.post, when to use Inertia.post. Thank you so much you saved my day

soleh's avatar
Level 1

@gych This works, however, the URL also changes to api/project/apply/filter in the address bar, is there a way i could keep the URL from changing?

gych's avatar
gych
Best Answer
Level 29

@soleh I personally use the same route for the filter/search post request as the current page's get request This way the URL stays the same.

For example if your page url is /project, you can use a route like this for the post request: Route::post('project', ProjectController::class, ''apply_filter')->name('project.filter');

In my projects I also use the same method for both requests. If the get request uses the index method, my post request for the search also uses the same index method. The post route should then be Route::post('project', ProjectController::class, 'index')->name('project.filter');

See this example:

    public function index(Request $request)
    {
		$page = 1;
        if($request->page) $page = $request->page;

        $query = Project::query();

        if($request->filter_items) {
            $query->whereIn('name', $filterItems)->paginate(10)->onEachSide(1);
        }
        
      	$filteredProjects = $query->paginate(10, ['*'], 'page', $page)->onEachSide(1);
		if($request->filter_items) $filteredProjects->appends($request->only(['filter_items']));

       	return inertia('Project/Index', [
            "projects" => ProjectResource::collection($filteredProjects),
        ]);
    }

I've also appended the filter items and added $page for your pagination. Also double check if the route names in my example are correct.

1 like
soleh's avatar
Level 1

@gych Great, everything works good now. Thank you so much for the help. I appreciate it

gych's avatar

@soleh No problem :) I'm glad I could help !

1 like

Please or to participate in this conversation.