Reputation: 251
I'm checking the laravel-debugbar and found that the amount of queries is twice as it should be (in my opinion)
While it should be called only once when rendering the view,
The Livewire Class :
class AllTodos extends Component
{
use WithPagination;
public $todoId;
protected $listeners = [
'todoAdded' => '$refresh',
'deleteConfirmed' => 'delete',
'completeConfirmed' => 'complete'
];
public function deleteConfirmation($id)
{
$this->todoId = $id;
$this->dispatchBrowserEvent('alertConfirmation', [
'message' => 'Are you sure want to delete this task ?',
'action' => 'deleteConfirmed'
]);
}
public function delete()
{
$todo = Todo::findOrFail($this->todoId);
$todo->delete();
$this->dispatchBrowserEvent('alertInfo', [
'message' => 'Todo has been deleted.',
'icon' => 'success'
]);
}
public function completeConfirmation($id)
{
$this->todoId = $id;
$this->dispatchBrowserEvent('alertConfirmation', [
'message' => 'Are you sure want to complete this task ?',
'action' => 'completeConfirmed'
]);
}
public function complete()
{
$todo = Todo::findOrFail($this->todoId);
$todo->update([
'is_completed' => 1
]);
$this->dispatchBrowserEvent('alertInfo', [
'message' => 'Todo has been completed.',
'icon' => 'success'
]);
}
public function render()
{
return view('livewire.all-todos', [
'todos' => Todo::latest()->paginate(5)
]);
}
}
The view :
<div>
<livewire:add-todo />
<table class="w-full m-4">
<thead class="text-md font-semibold tracking-wide text-left text-gray-900 bg-gray-100 uppercase border-b border-gray-600">
<th class="px-4 py-3">Title</th>
<th class="px-4 py-3">Action</th>
</thead>
<tbody class="bg-white">
@foreach($todos as $todo)
<tr class="text-gray-700">
<td class="px-4 py-3 border">{{ $todo->title }}</td>
<td class="px-4 py-3 border">
<button class="p-2 pl-5 pr-5 transition-colors duration-700 transform bg-indigo-500 hover:bg-blue-400 text-gray-100 text-lg rounded-lg focus:border-4 border-indigo-300" wire:click.prevent="completeConfirmation({{ $todo->id }})">Complete</button>
<button class="p-2 pl-5 pr-5 transition-colors duration-700 transform bg-red-500 hover:bg-red-400 text-gray-100 text-lg rounded-lg focus:border-4 border-red-300" wire:click="deleteConfirmation({{ $todo->id }})">Delete</button>
</td>
</tr>
@endforeach
</tbody>
</table>
<div class="m-4">
{{ $todos->links() }}
</div>
</div>
Update
The layouts :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet" type="text/css" />
@livewireStyles
<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>
</head>
<body>
<section class="container mx-auto p-6 font-mono">
<div class="w-full mb-8 overflow-hidden rounded-lg shadow-lg">
<div class="w-full overflow-x-auto">
<livewire:all-todos />
</div>
</div>
</section>
<x-alerts />
<script src="{{ asset('js/swal.js') }}"></script>
@stack('js')
@livewireScripts
</body>
</html>
I tried to use mount special method, its resulting this same double queries, How to reduce these amount of queries ?
Upvotes: 1
Views: 1873
Reputation: 26490
As we figured out in the comments, the issue here is that you don't have a slot in your layout - which is where the full-page Livewire component is injected. Instead, you render the component directly in your layout using <livewire:all-todos />
.
This means two things,
all-todos
component will be rendered on all your pages that uses that layout.This first point here, is why you are getting double queries.
To solve your issue, you simply have to replace the inline rendering of the compoinent which is <livewire:all-todos />
with the magic variable {{ $slot }}
.
<section class="container mx-auto p-6 font-mono">
<div class="w-full mb-8 overflow-hidden rounded-lg shadow-lg">
<div class="w-full overflow-x-auto">
{{ $slot }}
</div>
</div>
</section>
Upvotes: 1