Livewire: Problem with AlpineJS on fresh content in a livewire loop

Created on 11 Apr 2020  ·  3Comments  ·  Source: livewire/livewire

I have this problem where AlpineJS doesn’t seem to be activated on Livewire components when components are added after the initial page load. I’ll try to make this code example as abstract as possible. I left out all styling classes to make is easier to read.

Some details:
AlpineJS: <script /src/=“https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js” /defer/></script> in the head of the document.
Laravel: Version 7.5.2
Livewire: Version 1.0.12

resources/views/livewire/product-search

// There is a form here with some search selectors

@foreach($products as $product)
    <livewire:product-tile :product=“$product” :key=“$product->id”/>
@endforeach

resources/views/livewire/product-tile

<div x-data=“{ expanded: false }”>
    <div x-on:mouseover=“expanded = true” x-on:mouseleave=“expanded = false”>
        <div>
            {{ $product->name }}
        </div>
        <div :class=“{ ‘hidden’: expanded === false }”>
            <button>
                Buy
            </button>
        </div>
    </div>
</div>

After the initial page load all works well. All the product tiles are visible and when I hover over one of the tiles, the “buy” button appears.

Here is where it goes wrong
As soon as I changes some search selectors. Livewire injects the correct products based on the search selectors. But the newly injected product-tiles do not work with AlpineJS, the “buy” button is visible by default and there are no changes on mouse over and mouse leave.

Another strange behaviour
When I would add x-cloak on the tiles. This also works on the initial page load as expected. But just as the above problem, x-cloak will not be removed on newly injected tiles.

During all of the examples There are no errors shown in the console of the browser.

I really hope someone can help me out!

Needs Better Reproducibility

Most helpful comment

I've found a solution, or at least a workaround.

I've added this to resources/views/livewire/product-search

@push('scripts')
    <script>
        document.addEventListener("livewire:load", function(event) {
            window.livewire.hook('afterDomUpdate', () => {
                Alpine.start();
            });
        });
    </script>
@endpush

I'm not sure. It looks to me like Livewire should handle this by default after DOM Update, is it a bug?

All 3 comments

Small update:
When I replace <livewire:product-tile :product=“$product” :key=“$product->id”/> with the content of the component (so no nesting) it just suddenly works! But this is really messy since I have to use this component within several other pages.

Edit:
No, still no good. After a couple of times changing some search parameters it some product-tiles suddenly stop AlpineJS behavior as in the original problem description.

I've found a solution, or at least a workaround.

I've added this to resources/views/livewire/product-search

@push('scripts')
    <script>
        document.addEventListener("livewire:load", function(event) {
            window.livewire.hook('afterDomUpdate', () => {
                Alpine.start();
            });
        });
    </script>
@endpush

I'm not sure. It looks to me like Livewire should handle this by default after DOM Update, is it a bug?

Does this problem still persist? I just tried this locally and it worked.

Was this page helpful?
0 / 5 - 0 ratings