livewire: Can't return file download from method

My component represents a digital product. I’m using Spatie media library to attach files to my products. When I click on the download button, it should start downloading a file:

// wire:click="download"

public function download()
{
    $files = Product::find($this->productId)->getMedia('download');
    return MediaStream::create($this->title)->addMedia($files);
}

These two lines work just fine if I put them in a normal controller, but not in livewire. Are there any workarounds? The only quick fix that I can think of, and I don’t like at all, is to redirect the user to another route that downloads the file, ugh.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 23 (12 by maintainers)

Most upvoted comments

For fure use, this works fine in livewire force download

public function download(){

            $path       = public_path('Bla.pdf');
            $contents   = base64_decode('filecode');

            //store file temporarily
            file_put_contents($path, $contents);

            //download file and delete it
            return response()->download($path)->deleteFileAfterSend(true);
}

Jumping in here to say that I’m trying to use Livewire to download a file as well. I haven’t come up with a good way to do this yet but will update if I find a solution.

The redirect route method works… but seems to break the component from where the request was made.

i.e

  1. Click download link
  2. $this->redirectRoute('download'); is called as in above example.
  3. Click download link again. Now nothing happens. i.e. no requests are fired to the backend at all.
  4. Refresh the page and it works again.

One way to get around this is by catching an emitted event and then using vanilla JS to download the file.

<div x-data="{}"
     x-init="
         @this.on('download', file => {
            window.location = '/download?file='+file;
        })
">
    <button wire:click="download" class="btn btn-link">
        <x-heroicon-o-download class="w-6 h-6"/>
    </button>
</div>
public function download($path)
{
    $this->emitSelf('download', base64_url_encode($path));
}

I think the best way to handle this right now is redirecting to a separate route in charge of downloading. I don’t see an easy option here. Closing for now.

@mokhosh @xxdalexx if i had export excel file with givin array how can i redirect it with my array ? dont tell me to send it with the url by get method 😒

$arr = [1,2,3,4]; return Excel::download(new EncomesExport($arr), 'Encomes.xlsx');