-
Hi, I'm getting the following Livewire JS error when using a paginated component:
Not sure if this is a V3 bug or something I'm doing wrong, but I'm leaning towards bug? Version Info
Environment ..................................................................
Application Name ..................................................... Laravel
Laravel Version ...................................................... 10.28.0
PHP Version ............................................................ 8.2.7
Composer Version ....................................................... 2.5.8
Environment ............................................................ local
Debug Mode ........................................................... ENABLED
URL .................................................... super secret stuff
Maintenance Mode ......................................................... OFF
I have two Livewire components, with one included indirectly via the other.
<div>
<label for="in_stock" class="cursor-pointer">
<input type="checkbox" wire:model.live="in_stock" name="in_stock" id="in_stock" />
Only show items in stock
</label>
{{ $products->links() }}
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-10 gap-y-12 mt-10 transition-all duration-300 mb-10" wire:loading.class="opacity-0 max-h-0">
@foreach ($products as $product)
<x-product-teaser :product="$product" :category="$category" />
@endforeach
</div>
<div wire:loading.flex class="flex items-center justify-center">
<span class="block loading loading-spinner text-primary w-8 h-8 my-8"></span>
</div>
{{ $products->links() }}
</div> The
<div>
<livewire:product-single-add wire:key="product-single-add-{{ $product->id }}" :product="$product" :instance_id="$product->instance_id" />
</div>
So the heirarchy is:
Whenever I interact with the pagination or the filter tickbox it works the first time (although the console error is produced). Subsequent interactions no longer work and the Wire IDs mentioned in the log messages don't match the DOM IDs. The following things DO to work, so I think I must have stumbled on a strange combination.
Any ideas? |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 4 replies
-
Two key questions here: 1. What's the purpose of the child Livewire component "product-single-add"? 2. Why are you using a blade, just to add a nested component in? Not a bug as far as I can see, just a misunderstanding of how to use nested components. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the reply. The templates are far more complex than I posted above, but I've stripped most things out for brevity, the problem still exists in the simplified format above. The single-add component is livewire because it has live quantity stock checks and triggers events in other parts of the template. Wasn't relevant to the problem above but it is needed. The teaser blade template is used because we re-use this same display in several different places throughout the site. I have correctly keyed the child component in the example above, still looks like a bug to me! I will try to create a reproduction repo and share. |
Beta Was this translation helpful? Give feedback.
-
I have recreated the issue in a simple repository: |
Beta Was this translation helpful? Give feedback.
-
OK I found the issue, and it was my fault for not reading the docs thoroughly enough. The
https://livewire.laravel.com/docs/components#adding-wirekey-to-foreach-loops What is not clear from the docs is that if you have a CSS grid it seems you need to do something like: <div class="grid grid-cols-12">
@foreach ($items as $item)
<div class="col-span-3" wire:key="title-{{ $item->id }}">{{ $item->title }}</div>
<div class="col-span-3" wire:key="price-{{ $item->id }}">{{ $item->price }}</div>
<div class="col-span-3" wire:key="something-else-{{ $item->id }}">{{ $item->something_else }}</div>
@endforeach
</div> Adding unique keys to each element. |
Beta Was this translation helpful? Give feedback.
-
If it helps anyone I had exactly the same error. I followed the answer in this thread, but to no avail. Eventually I discovered I had more than a single element in my view. i.e.
The console error happened when I dispatched an event (any event), like this:
It took me forever to figure it out as the error seemed totally unrelated to what was actually wrong. |
Beta Was this translation helpful? Give feedback.
-
Just add another workaround for this issue. In my case, it was caused by a missing blade component. For example, I have a livewire/volt component like this: <div>
<x-card>
...
</x-card>
</div> After spending some hours finding the cause of this problem, I realized that I had forgotten to add the card component in |
Beta Was this translation helpful? Give feedback.
OK I found the issue, and it was my fault for not reading the docs thoroughly enough.
The
wire:key
has to be on the root element DIRECTLY inside the foreach loop. From the docs:https://livewire.laravel.com/docs/components#adding-wirekey-to-foreach-loops
What is not clear from the docs is that if you have a CSS grid it seems you need to do something like: