The error you're encountering, Undefined property: Illuminate\Pagination\LengthAwarePaginator::$username, is due to the fact that you're trying to access properties on a LengthAwarePaginator object, which is not how pagination works in Laravel.
When you use pagination, the paginate() method returns a LengthAwarePaginator instance, which is a collection of paginated items. You need to iterate over the paginated items to access individual properties.
Here's how you can modify your Livewire component to handle pagination correctly:
-
Remove the loop in the
mountmethod: You should not loop through users and paginate each one individually. Instead, you should paginate the entire query result. -
Modify the query to paginate the users: Use the
paginate()method directly on the query that retrieves the users.
Here's the corrected Livewire component:
namespace App\Livewire;
use App\Models\User;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
use Livewire\WithPagination;
class Team extends Component
{
use WithPagination;
public function render()
{
// Retrieve paginated users with their scores
$scoreList = DB::table('users')
->select(
'users.username',
DB::raw('COALESCE(SUM(points.points), 0) AS total_points'),
DB::raw('COALESCE(SUM(CASE WHEN games.winner_id = users.id THEN 1 ELSE 0 END), 0) AS total_wins'),
DB::raw('COALESCE(SUM(CASE WHEN games.cup_winner_id = users.id THEN 1 ELSE 0 END), 0) AS total_cups'),
DB::raw('COUNT(game_user.game_id) AS total_games_played')
)
->leftJoin('game_user', 'game_user.user_id', '=', 'users.id')
->leftJoin('games', 'game_user.game_id', '=', 'games.id')
->leftJoin('points', function ($join) {
$join->on('points.user_id', '=', 'users.id')
->on('points.game_id', '=', 'games.id');
})
->whereIn('users.id', User::role('member')->pluck('id'))
->groupBy('users.id')
->paginate(10); // Adjust the number of items per page as needed
return view('livewire.team', [
'scoreList' => $scoreList,
]);
}
}
In your Blade view (livewire.team), you can now iterate over $scoreList and use the pagination links:
<div class="relative overflow-x-auto">
<table class="w-full text-left rtl:text-right text-gray-500">
<thead class="text-gray-700 uppercase bg-gray-50 text-xs">
<tr>
<th scope="col" class="px-4 py-3">Username</th>
<th scope="col" class="px-4 py-3">G</th>
<th scope="col" class="px-4 py-3">P</th>
<th scope="col" class="px-4 py-3">W</th>
<th scope="col" class="px-4 py-3">C</th>
</tr>
</thead>
<tbody>
@foreach($scoreList as $score)
<tr class="bg-white border-b text-xs">
<th scope="row" class="px-4 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white">
{{ $score->username }}
</th>
<td class="px-4 py-2">
{{ $score->total_games_played }}
</td>
<td class="px-4 py-2">
{{ $score->total_points }}
</td>
<td class="px-4 py-2">
{{ $score->total_wins }}
</td>
<td class="px-4 py-2">
{{ $score->total_cups }}
</td>
</tr>
@endforeach
</tbody>
</table>
{{ $scoreList->links() }} <!-- Pagination links -->
</div>
This setup will paginate the users and their scores correctly, and you can navigate through the pages using the pagination links. Adjust the number of items per page in the paginate() method as needed.