paginationlaravel-8laravel-livewirealpine.jslaravel-pagination

Laravel Livewire 2 pagination breaks Alpine


I'd be happy to post some or all of my code, but for starters, here is the upshot. I have a Livewire view with Livewire components that are paginated. These items may also be filtered. However, any time I do any one of the following:

  1. Remove an item from the page (I have a method for this built in that removes the item)
  2. Change what is being filtered - (this is done by clicking on a tag)
  3. Change pages

All Alpine JS on the page breaks. Anything that is hidden via x-cloak becomes hidden, and anything that is hidden using x-show is visible. No click events, no store, nothing.

What I've tried:

  1. Removed all complex sub items from the nested items - basically the main implementations of javascript interactivity that break
  2. Added and removed wire:key attributes everywhere - even when doing so doesn't make sense. Also tried to make these extra dynamic with random strings or current time.
  3. Added hidden inputs and tried to bind the array of nested items to a model so I could use lifecycle methods - if nothing else just to debug when they fire.
  4. Logging each point when anything with alpine.js or livewire is executed.
  5. Modifying different properties on each component involved to try and trigger a different result

And nothing. No matter what, the result is more or less the same. Alpine just does not work after livewire activity. One thing that is very interesting though is that after each request, the Alpine:init function fires on the outer component, but that's it. I've tried turning it off to see whether that was the problem, but no luck.

Anything that can shed some light on this situation would be appreciated deeply.


Solution

  • Okay - I've solved it. The solution was breathtakingly simple, and I have only abstract guesses as to why it worked.

    My code was something like this:

    <div>
      @foreach($mediaItems as $item)
        <livewire:mediaItem :media="$item" key="mediaItem-{{$item}}"/>
      @endforeach
    </div>
    

    And the problem was that the media item would lose javascript interactivity after the first pagination or refresh, etc. For whatever reason, modifying it to the following fixed it instantly.

    <div x-data>
      @foreach($mediaItems as $item)
        <livewire:mediaItem :media="$item" key="mediaItem-{{$item}}"/>
      @endforeach
    </div>
    

    And that was it. I had to add an x-data on the immediate wrapping element in order for interactivity to remain. Even though the wrapping element was already inheriting x-data from it's parent, I needed to explicitly add it here.

    This cost me a ton of time, so if this solution helps anyone else, I'm glad to be of service.