phplaravellaravel-bladelaravel-livewire

Livewire: Unable to find component


I have a component using Laravel + livewire. I'm newbie in this but I get an example from
https://diarioprogramador.com/crear-crud-con-laravel-8-y-livewire/

When I execute php artisan serve I get this error>

Livewire\Exceptions\ComponentNotFoundException Unable to find component: [Productos] GET 127.0.0.1:8000 PHP 8.2.12 — Laravel 12.1.1

Last reference to my source is : resources\views\welcome.blade.php Line 278:

    <div class="container mx-auto p-4">

    @livewire('Productos')

    </div>

I have tried making again (php artisan make:livewire productos), ensure livewire is installed (composer require livewire/livewire), cleaning cache and migrate (php artisan optimize:clear & php artisan migrate), adding to app.blade.php the annotations (@livewireStyles @livewireScripts), check if component is added in view (@livewire('productos')), restarting server and project, changing the name of component 'productos' to 'Productos' and the error remains. AI also doesn't help.

This is my Controller (app/Http/Controllers/ProductoController.php):

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\ProductoService;

class ProductoController extends Controller
{
    protected $productoService;

    public function __construct(ProductoService $productoService)
    {
        $this->productoService = $productoService;
    }

    public function store(Request $request)
    {
        $status = $this->productoService->insertarProducto($request->all());
        return response()->json(['success' => $status == 1]);
    }

    public function update(Request $request, $id)
    {
        $status = $this->productoService->actualizarProducto($id, $request->all());
        return response()->json(['success' => $status == 1]);
    }

    public function show($id)
    {
        return response()->json($this->productoService->obtenerProducto($id));
    }

    public function destroy($id)
    {
        $status = $this->productoService->borrarProducto($id);
        return response()->json(['success' => $status == 1]);
    }
}

The livewire class (app/Livewire/Productos.php):

    <?php

    namespace App\Http\Livewire;

    use Livewire\Component;
    use Illuminate\Support\Facades\DB;

    class Productos extends Component
    {
        public $productos, $producto_id, $nombre, $descripcion, $precio;

        public function render()
        {
            $this->productos = DB::select("CALL obtenerTodosLosProductos()");
            return view('livewire.productos');
        }

        public function guardarProducto()
        {
            if ($this->producto_id) {
                DB::statement("CALL actualizarProducto(?, ?, ?, ?, @p_status)", 
                    [$this->producto_id, $this->nombre, $this->descripcion, $this->precio]);
            } else {
                DB::statement("CALL insertarProducto(?, ?, ?, @p_status)", 
                    [$this->nombre, $this->descripcion, $this->precio]);
            }

            $this->resetCampos();
        }

        public function editarProducto($id)
        {
            $producto = DB::select("CALL obtenerProducto(?)", [$id])[0];
            $this->producto_id = $producto->id;
            $this->nombre = $producto->nombre;
            $this->descripcion = $producto->descripcion;
            $this->precio = $producto->precio;
        }

        public function eliminarProducto($id)
        {
            DB::statement("CALL borrarProducto(?, @p_status)", [$id]);
        }

        public function cancelarEdicion()
        {
            $this->resetCampos();
        }

        private function resetCampos()
        {
            $this->producto_id = null;
            $this->nombre = '';
            $this->descripcion = '';
            $this->precio = '';
        }
    }

My view (resources/views/livewire/productos.blade.php):

    <div>
        <h2 class="text-2xl font-bold mb-4">Gestión de Productos</h2>

        {{-- Formulario para agregar y editar productos --}}
        <form wire:submit.prevent="guardarProducto">
            <div class="mb-2">
                <label class="block text-gray-700">Nombre:</label>
                <input type="text" wire:model="nombre" class="w-full p-2 border rounded">
            </div>

            <div class="mb-2">
                <label class="block text-gray-700">Descripción:</label>
                <textarea wire:model="descripcion" class="w-full p-2 border rounded"></textarea>
            </div>

            <div class="mb-2">
                <label class="block text-gray-700">Precio:</label>
                <input type="number" step="0.01" wire:model="precio" class="w-full p-2 border rounded">
            </div>

            <button type="submit" class="bg-blue-500 text-white p-2 rounded">
                {{ $producto_id ? 'Actualizar Producto' : 'Agregar Producto' }}
            </button>

            @if($producto_id)
                <button type="button" wire:click="cancelarEdicion" class="bg-gray-500 text-white p-2 rounded ml-2">
                    Cancelar
                </button>
            @endif
        </form>

        {{-- Tabla de productos --}}
        <table class="table-auto w-full mt-4 border-collapse border border-gray-200">
            <thead>
                <tr class="bg-gray-100">
                    <th class="border p-2">ID</th>
                    <th class="border p-2">Nombre</th>
                    <th class="border p-2">Descripción</th>
                    <th class="border p-2">Precio</th>
                    <th class="border p-2">Acciones</th>
                </tr>
            </thead>
            <tbody>
                @foreach($productos as $producto)
                    <tr>
                        <td class="border p-2">{{ $producto->id }}</td>
                        <td class="border p-2">{{ $producto->nombre }}</td>
                        <td class="border p-2">{{ $producto->descripcion }}</td>
                        <td class="border p-2">${{ number_format($producto->precio, 2) }}</td>
                        <td class="border p-2">
                            <button wire:click="editarProducto({{ $producto->id }})" class="bg-yellow-500 text-white p-1 rounded">
                                Editar
                            </button>
                            <button wire:click="eliminarProducto({{ $producto->id }})" class="bg-red-500 text-white p-1 rounded">
                                Eliminar
                            </button>
                        </td>
                    </tr>
                @endforeach
            </tbody>
        </table>
    </div>

And the welcome view (resources/views/welcome.blade.php):

        ...
            @livewireStyles
        @livewireScripts
        </body>
        </html>

Another way I did:

        @if (Route::has('login'))
            <div class="h-14.5 hidden lg:block"></div>
            <div class="container mx-auto p-4">
                @livewire('productos')
            </div>
        @endif

        @livewireScripts
    </body>

Solution

  • if your component class is in this path: The livewire class (app/Livewire/Productos.php)
    The problem might be in the namespace declaration inside of the Products.php file.
    You have it declared wrong with: App\Http\Livewire. It should be: App\Livewire