Reputation: 53
I´m using Laravel 8 with Livewire.
I have create this to show a list of items and the user can apply filters as well. Upon load the data gets shown, 10 records per page. However when I try to click next page or a specific page number I get the error "Call to a member function links() on array..."
I´m also using repository and it´s injected on the livewire component.
use App\Models\Repositories\Interfaces\LojaAdesaoRepositoryInterface;
use Livewire\Component;
use Livewire\WithPagination;
This is my component
class Adesao extends Component
{
use WithPagination;
protected $repository;
public $cnpj;
public $razaoSocial;
public $nomeFantasia;
public $regulamentacaoId;
public $regiaoId;
public $faturamentoId;
private $filtros = [
"cnpj" => "",
"razao_social" => "",
"nome_fantasia" => "",
//"regulamentacao_id" => "",
//"regiao_id" => "",
//"faturamento_id" => ""
];
private $lojas = [];
protected $listeners = ['regiaoMudanca' => 'regiaoMudanca', 'faturamentoListener' => 'faturamentoListener', 'regulamentacaoListener' => 'regulamentacaoListener'];
public function mount(LojaAdesaoRepositoryInterface $respository)
{
$this->repository = $respository;
$lojas = $this->retornaListaInicial();
$this->setLojas($lojas);
}
public function render(LojaAdesaoRepositoryInterface $respository)
{
$this->repository = $respository;
$lojas = $this->getLojas();
return view('livewire.lojas.adesao',['lojasAdesao' => $lojas]);
}
public function regiaoMudanca($value){
$this->filtros['regiao_id'] = $value;
}
public function faturamentoListener($value){
$this->filtros['faturamento_id'] = $value;
}
public function regulamentacaoListener($value){
$this->filtros['regulamentacao_id'] = $value;
}
public function submitForm(LojaAdesaoRepositoryInterface $respository){
$this->resetPage();
$this->repository = $respository;
$this->filtros["cnpj"] = $this->cnpj;
$this->filtros["razao_social"] = $this->razaoSocial;
$this->filtros["nome_fantasia"] = $this->nomeFantasia;
$lojas = $this->repository->filterBy($this->filtros);
$this->setLojas($lojas);
}
private function retornaListaInicial(){
return $this->repository->filterBy([]);
}
private function setLojas($lojas){
//dd($lojas->links());
$this->lojas = $lojas;
}
private function getLojas(){
return $this->lojas;
}
}
<div>
<x-nav-bar.nav/>
<form wire:submit.prevent="submitForm()" method="get">
<div class="container mx-auto px-4 sm:px-8">
<div class="flex justify-center pt-8 sm:justify-start sm:pt-0 text-gray-900 dark:text-white">
LOJA ADESÃO
</div>
<div class="grid grid-cols-1 md:grid-cols-3 border-t border-b border-gray-200 dark:border-gray-700">
<div class="p-3">
<div class="flex items-center">
<label class="block font-semibold text-gray-900 dark:text-white">CNPJ<label>
<input type="text" wire:model.defer="cnpj" maxlength="15" placeholder="CNPJ" name="cnpj" id="cnpj" class="w-full h-4 px-3 py-5 mt-2 hover:outline-none focus:outline-none border-none focus:ring-1 bg-white text-sm dark:bg-gray-800 rounded-md">
</div>
</div>
<div class="p-3">
<div class="flex items-center">
<label class="block font-semibold text-gray-900 dark:text-white">Razão Social<label>
<input type="text" wire:model.defer="razaoSocial" maxlength="60" placeholder="Razão Social" name="razaoSocial" id="razaoSocial" class="w-full h-4 px-3 py-5 mt-2 hover:outline-none focus:outline-none border-none focus:ring-1 bg-white text-sm dark:bg-gray-800 rounded-md">
</div>
</div>
<div class="p-3">
<div class="flex items-center">
<label class="block font-semibold text-gray-900 dark:text-white">Nome Fantasia<label>
<input type="text" maxlength="60" wire:model.defer="nomeFantasia" placeholder="Nome Fantasia" name="nomeFantasia" id="nomeFantasia" class="w-full h-4 px-3 py-5 mt-2 hover:outline-none focus:outline-none border-none focus:ring-1 bg-white text-sm dark:bg-gray-800 rounded-md">
</div>
</div>
<div class="p-3">
<div class="flex items-center">
<label class="block font-semibold text-gray-900 dark:text-white">Regulamentação<label>
<livewire:dropdown-list.regulamentacao />
</div>
</div>
<div class="p-3">
<div class="flex items-center">
<label class="block font-semibold text-gray-900 dark:text-white">Faturamento<label>
<livewire:dropdown-list.faturamento />
</div>
</div>
<div class="p-3">
<div class="flex items-center">
<label class="block font-semibold text-gray-900 dark:text-white">Região<label>
<livewire:dropdown-list.regiao />
</div>
</div>
<div class="p-3 col-start-3">
<button type="submit" class="text-gray-700 py-2 px-6 rounded-lg dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-gray-700 focus:outline-none">Aplicar Filtro</button>
<button type="reset" class="text-gray-700 py-2 px-6 rounded-lg dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-gray-700 focus:outline-none">Limpar Filtros</button>
</div>
</div>
</div>
</form>
<div class="container mx-auto px-4 sm:px-8">
<div class="py-8">
<div class="-mx-4 sm:-mx-8 px-4 sm:px-8 py-4 overflow-x-auto">
<div class="inline-block min-w-full shadow-md rounded-lg overflow-hidden">
<table class="min-w-full leading-normal border border-gray-200">
<thead>
<tr>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-left text-xs font-semibold text-gray-700 uppercase tracking-wider">
<input type="checkbox" name="all" id="all" class="rounded appearance-none checked:bg-blue-600 checked:border-transparent">
</th>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-white text-left text-xs font-semibold uppercase tracking-wider">
CNPJ
</th>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-white text-left text-xs font-semibold uppercase tracking-wider">
Razão Social
</th>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-white text-left text-xs font-semibold uppercase tracking-wider">
Nome Fantasia
</th>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-white text-left text-xs font-semibold uppercase tracking-wider">
Regulamentação
</th>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-white text-left text-xs font-semibold uppercase tracking-wider">
Região
</th>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-white text-left text-xs font-semibold uppercase tracking-wider">
Faturamento
</th>
<th class="px-5 py-3 border-b-2 border-gray-200 bg-gray-500 text-white text-center text-xs font-semibold uppercase tracking-wider">
Ação
</th>
</tr>
</thead>
<tbody>
@foreach ($lojasAdesao as $lojaAdesao)
<tr class="">
<td class="px-5 py-5 border-b border-gray-200 bg-white text-sm dark:bg-gray-800">
<input type="checkbox" class="rounded appearance-none checked:bg-blue-600 checked:border-transparent">
</td>
<td class="px-5 py-5 border-b border-gray-200 text-xs dark:bg-gray-800">
<p class="text-white whitespace-no-wrap">{{ $lojaAdesao->cnpj }}</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-xs dark:bg-gray-800">
<p class="text-white whitespace-no-wrap">{{ $lojaAdesao->razao_social }}</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-xs dark:bg-gray-800">
<p class="text-white whitespace-no-wrap">{{ $lojaAdesao->nome_fantasia }}</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-xs dark:bg-gray-800">
<p class="text-white whitespace-no-wrap">{{ $lojaAdesao->regulamentacao->descricao }}</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-xs dark:bg-gray-800">
<p class="text-white whitespace-no-wrap">{{ $lojaAdesao->endereco->estado->regiao[0]['descricao'] }}</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-xs dark:bg-gray-800">
<p class="text-white whitespace-no-wrap">{{ $lojaAdesao->faturamento->descricao }}</p>
</td>
<td class="px-5 py-5 border-b border-gray-200 bg-white text-center text-sm dark:bg-gray-800">
<button class="text-gray-700 dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-gray-700 px-6 rounded-lg focus:outline-none">Atualizar</button>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
{{$lojasAdesao->links()}}
</div>
</div>
</div>
</div>
<div class="container mx-auto px-4 sm:px-8">
<div class="grid grid-cols-1 md:grid-cols-4 dark:border-gray-700">
<div class="p-3">
<div class="flex items-center">
<button class="text-gray-700 py-2 px-6 rounded-lg dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-gray-700 focus:outline-none">Selecionar Pesquisador(a)</button>
</div>
</div>
<div class="p-3">
<div class="flex items-center">
<button class="text-gray-700 py-2 px-6 rounded-lg dark:text-gray-200 hover:bg-gray-300 dark:hover:bg-gray-700 focus:outline-none">Importar</button>
</div>
</div>
</div>
</div>
</div>
use App\Models\Repositories\Interfaces\LojaAdesaoRepositoryInterface;
use App\Models\LojaAdesao;
use App\Models\Repositories\Base\BaseRepository;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\DB;
use function PHPUnit\Framework\isNull;
class LojaAdesaoRepository extends BaseRepository implements LojaAdesaoRepositoryInterface
{
use HasFactory;
protected $model = null;
/**
* UserRepository constructor.
*
* @param Campos $model
*/
public function __construct(LojaAdesao $model)
{
parent::__construct($model);
$this->model = $model;
}
public function filterBy(array $filtros, int $pageSize=10) {
DB::enableQueryLog();
$result= $this->model->where(function($q) use ($filtros){
foreach($filtros as $key => $value)
{
if ( $this->ehCampoLike($key) && !empty($value) ){
$q->where($key, 'like', '%' . $value . '%');
}
else{
if (!empty($value) ){
$q->where($key,'=', $value);
}
}
}
})->orderBy('cnpj', 'asc')->paginate($pageSize);
//dd(DB::getQueryLog());
return $result;
}
private function ehCampoLike(string $filtro): bool{
if ( $filtro == "cnpj" || $filtro == "razao_social" || $filtro == "nome_fantasia"){
return true;
}
return false;
}
}
Upvotes: 1
Views: 2054
Reputation: 2041
Short answer
move this from mount
to render
method:
$lojas = $this->retornaListaInicial();
$this->setLojas($lojas);
Explanation
Notice your both methods mount
and render
, while mount is called once on component startup, render is called every server call. So somehow when you change the page, only render is called and $lojas = $this->getLojas();
returns its initial value, a empty array.
public function mount(LojaAdesaoRepositoryInterface $respository)
{
$this->repository = $respository;
$lojas = $this->retornaListaInicial();
$this->setLojas($lojas);
}
public function render(LojaAdesaoRepositoryInterface $respository)
{
$this->repository = $respository;
$lojas = $this->getLojas();
return view('livewire.lojas.adesao',['lojasAdesao' => $lojas]);
}
Upvotes: 2