I’m passing a paginated collection of products from my Livewire class into my Livewire component and it mostly works fine. However when I change page via the pagination (e.g. go from page 1 to page 2) I find that the currently hidden elements do not update.
For example, when I go to page 2 the <p>
containing the long description still shows the product->id from the corresponding product on page 1. However the <p>
containing the short description updates fine.
What am I doing wrong?
App/Livewire/ProductList.php
<?php
namespace AppLivewire;
use LivewireWithPagination;
use LivewireComponent;
use AppModelsProduct;
class ProductList extends Component
{
use WithPagination;
public function render()
{
$products = Product::paginate(20);
return view('livewire.product-list', [
"products" => $products,
]);
}
}
App/Resources/Views/Livewire/product-list.blade.php
<div class="grid grid-cols-4">
@foreach ($products as $product)
<div x-data="{expanded{{$product->id}}:false}" href="#">
<p x-show="!expanded{{$product->id}}">
{{$product->short_description}}
</p>
<a x-show="!expanded{{$product->id}}" x-on:click="expanded{{$product->id}}=true">
Read More
</a>
<p x-show="expanded{{$product->id}}">
{{$product->long_description}}
</p>
<a x-show="expanded{{$product->id}}" x-on:click="expanded{{$product->id}}=true">
Read Less
</a>
</div>
@endforeach
</div>
<div id="productPagination">
{{ $products->links() }}
</div>
2
Answers
It appears that Livewire updates the DOM but Alpine’s variables are misaligned, perhaps because they are dynamically composed (using the record id).
A solution can be to introduce an id attribute in the main <div> of each row that varies on every update to let Alpine understand that it must reinitialize the object because the HTML is different
Two things, first you need to ensure that your view contains only one root element. To achieve this I’ve wrapped the entire view in a
div
.Secondly, you need to provide a
wire:key
to the root element within the loop, and provide it a unique value.Also
href
is not a valid attribute on adiv
tag.