I am trying to recreate a reusable blade component that will allow me to view and upload images for all my forms. The value in the livewire component could be a string of a previously uploaded image or a newly uploaded image.
What I need it the component to show me what image I have already set and the image Im am changing it to.
I have my livewire component that has a form with an image variable
class CreateStall extends Component
{
use WithFileUploads;
public editStallForm $form;
public function render()
{
return <<<'HTML'
<div>
<x-inputs.image wire:model="form.image" />
</div>
HTML;
}
}
I then have my image blade component that is responsable for showing the current image and the new image
<label >
<input wire:model="{{ $attributes->wire('model')->value() }}" type="file" class="hidden" accept=".svg,.png,.jpg,.jpeg,.gif" />
@if ($image)
@if (is_string($image))
<img src="{{ Storage::url($image) }}" class="absolute inset-0 aspect-auto w-full lg:max-h-64 lg:w-auto">
@elseif ($image instanceof LivewireTemporaryUploadedFile)
<img src="{{ $image->temporaryUrl() }}" class="absolute inset-0 aspect-auto w-full lg:max-h-64 lg:w-auto">
@endif
@endif
</label>
I have tried multiple ways of getting the image to the component… The most success ive had is with the x-data="image: @entange($attributes->wire(‘model’)" but i can seem to find a way to allow it to update with the value changes
2
Answers
You’re creating a reusable image upload component with Livewire. You want to display the current image and the newly uploaded image.
To achieve this, you’ll need to:
Pass the current image URL to the component.
Update the component when a new image is uploaded.
Here’s an updated version of your code:
CreateStall.php (Livewire Component)
image.blade.php (Component)
Explanation
We added a currentImage prop to the image component to display the initial image.
In the CreateStall component, we updated the image property when a new image is uploaded using the updatedImage method.
We use Alpine.js to manage the image display in the image component. We create an imageData function that takes the image and currentImage as arguments.
We used x-data to initialize the component with the imageData function.
We used x-on:change to update the image display when a new image is uploaded.
We used x-show to display the image conditionally.
This should solve the issue of updating the image display when a new image is uploaded.
Update:
The issue is due to the execution order in Alpine.js.
The x-data directive is executed after the template has been rendered, which means the image is undefined when the template is first rendered.
To fix this, you can use a slight modification to your code:
The issues you’re experiencing are due to:
Alpine.js rendering the :src attribute as src and then Livewire updating the image with a temporary URL, resulting in duplicate src attributes.
x-data not calling imageData function.
To resolve these issues:
Duplicate src attribute
Use x-bind:src instead of :src to bind the src attribute:
PHP
<img x-bind:src="image" class="absolute inset-0 aspect-auto w-full lg:max-h-64 lg:w_auto">
x-data not calling imageData function
You’re passing a string to x-data, but it expects a JavaScript object or function.
Try changing x-data to:
PHP
x-data="{ imageData: imageData(@json($currentImage)) }"
Or, for better readability:
PHP
Then, define the imageData function inside the x-data object:
PHP
However, I recommend simplifying your code. You don’t need the imageData function. Instead, initialize the image directly:
PHP
x-init="updateImageDisplay"
x-on:change="updateImageDisplay"
And update the updateImageDisplay function accordingly.
Full updated code
PHP