I’m struggling with a simple livewire component. It’s a button that adds or removes ids from an array (and also to the session). After adding a modal should appear with the different attributes.
The other components are not updating when the toggle method is called, same for the modal.
Loop:
@foreach ($listings as $listing)
<h1>{{$listing->title}}</h1>
<livewire:compare-listings :listing="$listing"/>
@endforeach
CompareListings.php
namespace AppLivewire;
use AppModelsListing;
use LivewireAttributesSession;
use LivewireComponent;
class CompareListings extends Component {
public Listing $listing;
#[Session]
public array $comparisonList = []; // List of IDs
public function toggleComparison($id): void {
if (!in_array($id, $this->comparisonList)) {
// Add ID
$this->comparisonList[] = $id;
} elseif (($key = array_search($id, $this->comparisonList)) !== false) {
// Remove ID
unset($this->comparisonList[$key]);
// Sort array
$this->comparisonList = array_values($this->comparisonList);
}
}
public function render() {
return view('livewire.compare-listings', [
'listings' => Listing::whereIn('id', $this->comparisonList)->get()
]);
}
}
compare-listings.blade.php
<div>
<button data-modal-target="compareModal" data-modal-toggle="compareModal"
class="mt-4 bg-gray-700 text-white px-4 py-2 rounded">
{{ __('Show comparison list') }}
</button>
<button wire:click="toggleComparison({{ $listing->id }})">
{{ __('Add/Remove comparison list') }}
</button>
@php
var_dump($comparisonList);
@endphp
{{-- <!-- Modal -->--}}
@push('modals')
<div id="compareModal" tabindex="-1">
Comparison Table
</div>
@endpush
2
Answers
I had to place a dispatch event that calls a method to update the component. It`s not very performant so I think about refactoring it via JavaScript.
Solution:
At the end of the method toggleComparison()
Add a new method
This solves the problem.
The question is not entirely clear, however from what I see, you are not assigning a unique key to the component included in the loop. This can cause incorrect synchronization between the rendered view and the view already displayed
In this way the compare-listings view receives a unique key (the record id) and is updated correctly. Here you can find the related documentation.
An additional tip
You can avoid traversing the $comparisonList array twice when deleting an element (the first time with in_array, the second time with array_search) by simply refactoring the toggleComparison() method like this: