Hey @Tasty_Arrival,
i had the same problem yesterday and tried to gather information how to achieve this using FilePond. Turns out FilePond is capable of doing this, but it was kind of hard to find a working way, which integrates with Livewires implementation.
That being said, i managed to get it working, even removing the image using only the normal FilePond functionality.
First of all, this is how my FilePond component looks like:
@props([
'baseurl' => false,
'filename' => false,
])
<div
wire:ignore
x-data
x-init="
FilePond.create($refs.input, {
allowMultiple: {{ isset($attributes['multiple']) ? 'true' : 'false' }},
server: {
process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => {
@this.upload('{{ $attributes['wire:model'] }}', file, load, error, progress)
},
revert: (filename, load) => {
@this.removeUpload('{{ $attributes['wire:model'] }}', filename, load)
},
load: (uniqueFileId, load, error, progress, abort, headers) => {
fetch(`{{ route('media.restore', ['course', $filename]) }}`).then((res) => {
return res.blob();
}).then(load);
},
},
@if($baseurl && $filename)
files: [
{
source: '{{ $filename }}',
options: {
type: 'local',
},
}
],
onremovefile: (error, file) => {
@this.set('{{ $attributes['wire:model'] }}', null);
}
@endif
});
"
>
<input type="file" {{ $attributes->only('accept') }} x-ref="input">
@error($attributes['name'])
<div class="text-sm text-red-600 mt-2">{{ $message }}</div>
@enderror
</div>
I modified it quite a bit to what looks like when you followed the Screencasts or looked into the surge repo.
The important parts are:
-
The FilePond options have been moved to the second parameter of the “create” method. Otherwise the Options would be globally set and it wouldn’t be possible to have more than one component per page.
-
As per the documentation of FilePond the “load” callback is used to load already existing files. So i created an endpoint which will return the requested file, in the way FilePond wants it (File Object, with Content-Disposition: inline header set). I simply fetch the file using the route and return the file blob.
-
Only when the BaseURL and the Filename props are set, i add the “files” configuration to the FilePond Object. To be able to remove an image using the preview i also use the “onremovefile” callback, which is called when you click on the “x” in the upper left corner of the FilePond “component”. When it’s clicked i simply set the wired property in my Livewire component to “null”. This signals me to delete the file on save.
Here is my Endpoint for loading the image (the route is protected using the auth guard)
You shouldn’t use the Controller as is, as even though it is protected through the auth middleware, it provides security vulnerabilities! You could pass in any Disk and Filename and the file would be returned! This is only for testing purpose and for the “sake of simplicity”!
class RestoreMediaController extends Controller
{
public function __invoke(string $disk, string $fileName)
{
return response()->file(Storage::disk($disk)->path($fileName), [
'Content-Disposition' => "inline; filename={$fileName}"
]);
}
}
Now when i save the Model i simply check, whether the original value is not equal to the current one and if so, i delete the old image and set the the attribute to either the new value or to null:
if ($this->course->image !== $this->image) {
Storage::disk('course')->delete($this->course->image);
$this->course->image = is_null($this->image) ? null : $this->image->store('/', 'course');
}
In my tests this worked seamlessly. I’m not sure whether there is some pitfall i can’t see at the moment or maybe there is a way better approach. But at least it works as it should 
Hope this helps anyone with the same problem. When someone needs help, please feel free to reach out 