Anybody using spatie/laravel-query-builder with Livewire?

Hi!

Is anybody using spatie/laravel-query-builder with Livewire?

If so, how did you make it all work together?

1 Like

Out of curiosity, is there an advantage you found for using it (within livewire)? I looked at it briefly when I was trying to find an easier solution to Passing an Eloquent (or query) Builder as a parameter, but quickly moved on because it was no help there. From the little I read, I remember thinking that it seemed like a great package for highly dynamic api endpoints, but for anything else I didn’t think the added benefit outweighed the added configuration. But again, I didn’t look to deep, and I’m always happy to be proven wrong.

I would also like to know this. How to set this up so that laravel query builder features can be used with Livewire without reloading the page.

Because as I see now, these two do not work together with subsequent requests from livewire.

I have it working but it is hacky :smiley:
It works with query update and filters the results.

On the component:

public $filter = [];
protected $updatesQueryString = ['filter']; 

 return view('livewire.items', [
            'items' => new (ItemsQuery($this->filter))->paginate()
        ]);

Then I have query class:

class ItemsQuery extends \Spatie\QueryBuilder\QueryBuilder
{
    public function __construct(array $filter = [])
    {
 request()->query->set('filter', $filter);

$query = Item::query()
 parent::__construct($query, request());
        $this->request->query->set('filter', $filter);

$this->allowedFilters(....);
}
}
1 Like

I use this at the moment.

<?php

namespace App\Http\Livewire;

use App\Item;
use Livewire\Component;
use Spatie\QueryBuilder\QueryBuilderRequest;

class Table extends Component
{
    /** @var QueryBuilderRequest */
    protected $request;

    /** @var array<string,string> */
    public $filter = [];

    /** @var array<string> */
    protected $updatesQueryString = [
        'filter',
    ];

    public function mount(): void
    {
        $this->filter = $this->request()->query('filter', $this->filter);
    }

    public function request(): QueryBuilderRequest
    {
        if (!$this->request) {
            $this->request = app(QueryBuilderRequest::class);
        }

        return $this->request;
    }

    public function filter(string $filter, ?string $slug): void
    {
        if (is_null($slug)) {
            unset($this->filter[$filter]);
        } else {
            $this->filter[$filter] = $slug;
        }

        $this->request()->query->set('filter', $this->filter);
    }

    public function render(): View
    {
        $items = QueryBuilder::for(Item::query(), $this->request())
            ->get();

        return view('livewire.table', [
            'items' => $items,
        ]);
    }
}

And in my filter views I use:

<a role="button" href="#" wire:click.prevent="filter('filter-name', 'filter-value')">Filter!</a>
1 Like

Thanks guys, that are two possible implementations were we could start with.

Great to hear we do not have to drop the great Query Builder package from Spatie!