Infinite Scroll with Livewire

Building a web site for an auction, we wanted an infinite scroll of lots as many lots where expected.

The web application is a Laravel project with Livewire for the views.

The Livewire Component

The list of lots is a Livewire component:

<?php
namespace App\Http\Livewire\Catalogue\Lot;
use Livewire\Component;
use Illuminate\Database\Eloquent\Builder;
use App\Lot;
use App\Auction;
class LotList extends Component
{
        public $count;
}

$count tracks the number of lots to show on the screen.

We render the view with:

public function render()
{
    return view('livewire.catalogue.lot.lot-list', [
        'subdomain' => $this->subdomain,
    ]);
}

Using the computed property,

public function getLotsProperty()
{
    $query = Lot::query();

    $lots = $query
        ->orderBy('updated_at', 'asc')
        ->take($this->count)
        ->get();
    return $lots;
}

So we take $count items.

The Blade View

We use Tailwind to construct the view,

<div class="flex flex-start flex-wrap items-stretch 
    min-w-full mt-2 mb-2">      
@foreach($lots as $lot)        
      <div wire:click="showLot({{ $lot->id }})">           
              ...  
          </div>        
    @endforeach
</div>

Infinite Scroll

Listen on the window scroll event,

@push('scripts')
    <script>
        window.onscroll = function(ev) {
            if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
                window.livewire.emit('loadMore')
            }
        };
    </script>
@endpush

The Livewire component has a listener for the loadMore event,

protected $listeners = [
    'loadMore' => 'load_more',
];

The listener updates the count of lots to be shown, thereby causing a rendering of the view with more ad infinitum.

public function load_more()
{
    $this->skip = $this->skip + config('catalogue.page_scroll');
}