Laravel Invoke or render a component directly from a route or controller

Viewed 296

I have a component

class Projects extends Component
{

    public $projects;

    public function __construct()
    {
        $this->projects = Project::get();
    }

    public function render()
    {
        return view('components.projects');
    }
}

and the corresponding components/projects.blade.php file containing

@dump($projects)

I saw somewhere it is possible to return the component view directly from a route. However, none of these works

Route::get('projects1', Projects::class); // error

Route::get('projects2', [Projects::class]); // error

Route::get('projects3', [Projects::class, 'render']); // view does not have access to public $projects

Route::get('projects4', [Projects::class, '__construct']); // renders blank

Route::view('projects5', 'components.projects'); // view does not have access to public $projects

Route::get('projects6', fn() => view('components.projects'));  // view does not have access to public $projects

Route::get('projects7', fn() => <<<'blade'
    <x-projects></x-projects>
blade); // component not accessed

Any clue?

When components/projects.blade.php contains

 @dump(get_defined_vars())

I see

array:5 [▼
  "__path" => "...\storage\framework\views/80c6e39e032dd35edb0d114508f22feaa7951180.php"
  "__data" => array:3 [▶]
  "__env" => Illuminate\View\Factory {#1791 ▶}
  "app" => Illuminate\Foundation\Application {#4 ▶}
  "errors" => Illuminate\Support\ViewErrorBag {#1811 ▶}
]

projects is missing when using

Route::view('projects5', 'components.projects'); 

The component class is not active, only the blade file.

When using either

return view('components.projects');

return (new Projects)->render();

return app(Projects::class)->render();

from a controller, I get the same results.

The only way I can make it act as a component is going via a blade file containing

<x-projects></x-projects>

In that case, I see, as expected for a component:

array:10 [▼
  "__path" => "...\storage\framework\views/80c6e39e032dd35edb0d114508f22feaa7951180.php"
  "__data" => array:8 [▶]
  "__env" => Illuminate\View\Factory {#1793 ▶}
  "app" => Illuminate\Foundation\Application {#4 ▶}
  "errors" => Illuminate\Support\ViewErrorBag {#1813 ▶}
  "projects" => Illuminate\Database\Eloquent\Collection {#1831 ▶}
  "componentName" => "projects"
  "attributes" => Illuminate\View\ComponentAttributeBag {#1820 ▶}
  "slot" => Illuminate\Support\HtmlString {#1823 ▶}
  "__laravel_slots" => array:1 [▶]
]

I wish to avoid to use an intermediate file only referencing the component.

1 Answers
Related