Floortje123421
Floortje123421

Reputation: 59

Laravel Livewire Component Not Rendering View Content

I am working on a Laravel project using Livewire and I've encountered an issue where my Livewire component's view is not rendering any content on the page. When navigating to the route associated with the component, the page loads without errors but the content is not displayed. I have verified that the component's render method is being called by adding log statements.

Here's the relevant code: app/Livewire/ManageUsers.php:


namespace App\Livewire;

use Livewire\Component;
use App\Models\User;
use Spatie\Permission\Models\Role;

class ManageUsers extends Component
{
    public $users = [];
    public $roles = [];
    public $selectedRole = [];
    public $newUserEmail = '';
    public $newUserName = '';
    // public $users;

    public function mount()
    {
        $this->users = User::all();
        $this->roles = Role::pluck('name', 'id')->toArray();

        foreach ($this->users as $user) {
            $userRoles = $user->getRoleNames();
            $this->selectedRole[$user->id] = $userRoles->isEmpty() ? null : $userRoles[0];
        }
    }
    
    public function updateUserRole($userId)
    {
        $user = User::find($userId);
        
        if ($user) {
            $user->syncRoles([$this->selectedRole[$userId]]);
        }
    }

    public function addUser()
    {
        $user = User::create([
            'name' => $this->newUserName,
            'email' => $this->newUserEmail,
            'password' => bcrypt('password')  // Standaard wachtwoord
        ]);

        $this->users->prepend($user);
    }

    public function render()
    {
        return view('livewire.manage-users');
    }
}

app/Http/Middleware/RoleMiddleware.php

<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class RoleMiddleware
{
    public function handle(Request $request, Closure $next, $role)
    
    {
        \Log::info('Handling request in middleware...');
        if (!$request->user() || !$request->user()->hasRole($role)) {
            abort(403);
        }
        \Log::info('Rendering view...' . $request->user()->name . ' ' . $role . ' ' . $request->user()->hasRole($role));
        return $next($request);
    }
}


resources/views/manage-users.blade.php:


@extends('layouts.app')


@section('content')
    <div class="container mx-auto mt-5">
        <h1 class="text-2xl mb-5">Beheer Permissies</h1>
        
        <livewire:manage-users />
        
    </div>
@endsection


resources/views/livewire/manage-users.blade.php:

<div>
    
    <div>
        <input type="text" wire:model="newUserName" placeholder="Naam">
        <input type="email" wire:model="newUserEmail" placeholder="Email">
        <button wire:click="addUser">Voeg gebruiker toe</button>
    </div>

    <table>
        <thead>
            <tr>
                <th>Naam</th>
                <th>Email</th>
                <th>Rol</th>
                <th>Acties</th>
            </tr>
        </thead>
        <tbody>
            @foreach($users as $user)
                <tr>
                    <td>{{ $user->name }}</td>
                    <td>{{ $user->email }}</td>
                    <td>
                        <select wire:model="selectedRole.{{ $user->id }}" wire:change="updateUserRole({{ $user->id }})">
                            <option value="">Geen</option>
                            @foreach($roles as $role)
                                <option value="{{ $role }}">{{ $role }}</option>
                            @endforeach
                        </select>
                    </td>
                    <td>
                    </td>
                </tr>
            @endforeach
        </tbody>
    </table>
</div>

routes/web.php

<?php

use Illuminate\Support\Facades\Route;
use App\Livewire\WeeskinderenTable;
use App\Http\Middleware\SetUserLanguage;
use App\Livewire\ManageUsers;


Route::get('/manage-users', ManageUsers::class)
->name('amanage-users')
->middleware(['auth', 'role:admin']);

The log statement outputs as expected, and the data that should be passed to the view exists and is valid. The problem seems to be with displaying the content in the view.

What I've tried:

Checked that the route is configured correctly and pointing to the Livewire component. Cleared route, view, and config caches using artisan commands. Checked the browser console for JavaScript errors (none found). Verified that the Livewire CSS and JS assets are correctly included in the layout. Despite these steps, the page remains blank. Any insights into what might be going wrong or troubleshooting steps would be appreciated.

update:

I found that when I define my route to return the view directly, it works well:

Route::get('/manage-users', function() { return view('manage-users'); })->name('manage-users');

But, when the route points directly to the Livewire component, the page is empty:

 Route::get('/manage-users', ManageUsers::class) ->name('manage-users') ->middleware(['auth', 'role:admin']);

In the latter, the render method in the component is called, but the view isn’t rendered as expected, with no errors in Laravel logs or JS console. Any insights would be appreciated!

Upvotes: 2

Views: 2889

Answers (1)

Muhammad At-Tauhidi
Muhammad At-Tauhidi

Reputation: 93

You havent included your layout file, but that may be the problem.

I encountered a similar issue upgrading an old project from Livewire 1 to Livewire 2.

In my case, the issue was with my layout file (app.blade.php). My layout was using a traditional Laravel style layout that uses a @yield directive to render content, e.g.:

@section('body')
<div id="app">
    @yield('content')   
</div>
@endsection

By default, Livewire 2 expects app.blade.php to use the new Blade component $slot syntax in the layout:

<!-- Before -->
<html>
    <body>
        @yield('content')
 
        @livewireScripts
    </body>
</html>
 
<!-- After -->
<html>
    <body>
        {{ $slot }}
 
        @livewireScripts
    </body>
</html>

If you can't modify your layout to use the $slot syntax, alternatively, you can specify the layout and the @section where livewire is rendered directly inside the render() method:

class ShowPosts extends Component
{
    public function render()
    {
        return view('livewire.show-posts')
            ->extends('layouts.app')
            ->section('body');
    }
}

Here the ->section('body') renders Livewire in to the @section('body') of my layout in app.blade.php .

See: https://laravel-livewire.com/docs/2.x/upgrading

Upvotes: 2

Related Questions