I originally had ma DB eloquent call in the mount()
method in the livewire component, but then I felt like it is not actually called only once as my attributes were rewritten, so I moved them to Laravel's controller.
Now in Laravel Controller
public function photos() {
$photos = Image::all();
foreach ($photos as $photo) {
$photo->imgLqPath = Storage::disk('s3')->temporaryUrl($photo->path025, now()->addHour());
$photo->imgPath = Storage::disk('s3')->temporaryUrl($photo->path, now()->addHour());
}
return view('cs.photos', [
'photos' => $photos
]);
}
then pass these photos to the component with
@livewire('cs.photos', ['photos' => $photos])
now in component's view, I looped them out to see what is happening to them
@foreach ($photos as $ph)
<pre>{{ json_encode($ph->getAttributes(), JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE) }}</pre>
@endforeach
resulting in
{
"id": 204,
"name": "long_name.png",
"path": "long_path.png",
"description": null,
"path025": "long_path.png",
"user_id": 5,
"coord_id": null,
"gpsx": 12.3,
"gpsy": 45.56,
"imageable_type": "App\\CS",
"imageable_id": 193,
"created_at": "2021-07-24 14:02:30",
"updated_at": "2021-07-24 14:02:30",
"imgLqPath": "https:\/\/path...",
"imgPath": "https:\/\/path..."
}
With this I am happy, however, whenever I call any action via wire:click
(i also tried .stop
and .prevent
.
<img
class="card-img-top"
src="{{ $photo->imgLqPath }}"
alt="..."
height="200px"
style="object-fit: contain;"
wire:click="selectPhoto({{ $photo }})"
>
(does not matter whether the action does something, the problem happens even with the blank body of the function)
public function selectPhoto(Image $photo)
{
// $this->photo = $photo;
// $this->emit('photoSelected', 'test');
}
My loop for photo attributes changes to this
{
"id": 204,
"name": "long_name.png",
"path": "long_path.png",
"description": null,
"path025": "long_path.png",
"user_id": 5,
"coord_id": null,
"gpsx": 12.3,
"gpsy": 45.56,
"imageable_type": "App\\CS",
"imageable_id": 193,
"created_at": "2021-07-24 14:02:30",
"updated_at": "2021-07-24 14:02:30"
}
seems like their attributes were reset to the original, but I'm clueless why that could happen.
To the livewire component controller, I added:
public function hydratePhotos($value) {
dd($value);
}
Which dumps a collection of photos without the path
attributes, so this seems to be the problem. I'm not sure how to solve it yet tho, so if no answer comes here before I do, I will update again.
Unlike what one might "feel", the Livewire requests are stateless - meaning that any data is sent back and forth between requests - and some data is retrieved from the database on each request. For models and collection of models, they are queried from the database between each request - only the models class and key is stored in the request.
This means that when your component rehydrates on subsequent requests, you have to re-apply those custom properties. If we assume that you have a collection in the property $photos
on your Livewire component, you can do
public function hydrate()
{
foreach ($this->photos as $photo) {
$photo->imgLqPath = Storage::disk('s3')->temporaryUrl($photo->path025, now()->addHour());
$photo->imgPath = Storage::disk('s3')->temporaryUrl($photo->path, now()->addHour());
}
}