AlexSteele's avatar

Livewire 3 Pagination and DB Facade question

I was trying to get pretty sophisticated with a livewire component that allowed inline editing and pagination. I kept running into this issue of needing to declare a property for, let's say, services as an example. so I struggled with that a while, until someone helped me in an earlier question. Thanks, @snapey... I concluded that inline editing is neat, but the design pattern of modal editing is also pretty common and it was much easier to implement.

This is a question about logic and best practices, really.

f we use eloquent, then we can take advantage in livewire 3 of the built in pagination. which is awesome. however, if we use DB facade, or are returning collection as an array - there appears to be some more complex steps needed, and it looks like Illuminate\Pagination\LengthAwarePaginator may be the way to handle that.

However, I may be a little bit spoiled because I would prefer to let laravel and livewire handle the pagination. Am I wrong (I hope I am)? Is there actually a way to use DB facade and automatic pagination, or must one use manual pagination with it?

0 likes
2 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

When using Livewire, you can indeed take advantage of Laravel's built-in pagination features, even when using the DB facade. However, you need to manually create a paginator instance since the DB facade returns a Builder instance, not a Model or Eloquent\Builder instance which has the paginate method.

Here's how you can use the LengthAwarePaginator with the DB facade:

use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
use Livewire\Component;
use Livewire\WithPagination;

class YourLivewireComponent extends Component
{
    use WithPagination;

    public function render()
    {
        $perPage = 10; // Number of items per page
        $page = request()->page ?: 1; // Current page
        $pageStart = ($page - 1) * $perPage; // Calculate the starting point

        // Get the total number of records
        $total = DB::table('services')->count();

        // Retrieve the items for the current page
        $services = DB::table('services')
            ->offset($pageStart)
            ->limit($perPage)
            ->get();

        // Create a new LengthAwarePaginator instance
        $paginator = new LengthAwarePaginator(
            $services,
            $total,
            $perPage,
            $page,
            ['path' => request()->url(), 'query' => request()->query()]
        );

        return view('livewire.your-view', [
            'services' => $paginator
        ]);
    }
}

In your Blade view, you can then render the pagination links as you would with Eloquent:

<div>
    {{-- Your table or list here --}}

    {{ $services->links() }}
</div>

This manual approach allows you to use the DB facade and still have pagination in your Livewire components. However, if you can use Eloquent models, it's generally simpler and more convenient, as you can just call the paginate method directly on the model query:

$services = Service::paginate(10);

And then in your Blade view:

<div>
    {{-- Your table or list here --}}

    {{ $services->links() }}
</div>

Using Eloquent also provides additional benefits, such as easier data manipulation and the ability to use relationships and other Eloquent features. If possible, prefer using Eloquent over the DB facade for these reasons.

1 like

Please or to participate in this conversation.