phplaravellaravel-bladelaravel-livewire

Uncaught Could not find Livewire component in DOM tree in dependent select form


I'm try to made a dependent form whit Laravel and Livewire, filling one of de select depending of de selected value of the other. When I select the value in the first select, JS console give the messege "Uncaught Could not find Livewire component in DOM tree".

This are my files

app/Livewire/SearchProducto.php

<?php

namespace App\Livewire;

use App\Models\Lineas;
use Livewire\Attributes\Computed;
use Livewire\Component;
use Illuminate\Support\Facades\DB;

class SearchProducto extends Component
{

    public $lineaID;
    public $versionID;
    public $categoriaID;

    #[Computed()]
    public function lineas()
    {
        return Lineas::all();
    }

    #[Computed()]
    public function versiones()
    {
        $versiones = DB::table('productos')
        ->select(DB::raw('distinct versions.id, versions.nombre as version'))
        ->leftjoin('versions', 'versions.id', '=', 'productos.version_id')
        ->where('productos.linea_id', '=', $this->lineaID)
        ->get();

        return $versiones;
    }

    public function render()
    {
        return view('livewire.search-producto');
    }
}

resources/views/livewire/search-producto.blade.php

@extends('layouts.maestro', ['head' => 'Productos'])

@section('content')
@livewireScripts
<div>
    <select wire:model.live="lineaID">
        <option value="">Línea</option>
        @foreach ($this->lineas as $linea)
            <option wire:key="{{ $linea->id }}" value="{{$linea->id}}">{{$linea->nombre}}</option>
        @endforeach
    </select>
    <select wire:model="versionID">
        <option>Versión</option>
        @foreach ($this->versiones as $version)
            <option wire:key="{{ $version->id }}" value="{{$version->id}}">{{$version->version}}</option>
        @endforeach
    </select>
</div>
    
@endsection

The line in routes/web.php is

Route::get('/searchProducto', SearchProducto::class);

I modified the next lines in app/config/livewire.php

'layout' => 'layouts.app', 'inject_assets' => false,

If i use @livewireScripts in layout.app, console give the messege "Detected multiple instances of Livewire running", thas why I put them in the form view. I start my app with breeze, so I delete the corresponding calls to Alpine from resources/js/app.js.

Before give me the alredy mentioned messege, JS console give me the follow warning: "Livewire: missing closing tags found. Ensure your template elements contain matching closing tags.", but it's just a warning.

In blade, I'm jumping into a intermediate layout ('maestro.blade.php') and then jump into app.blade.php. I appreciate any help in advance, and sorry for my english, I'm not a native speaker.

I'm try to made a dependent form whit Laravel and Livewire, filling one of de select depending of de selected value of the other.


Solution

  • If is useful for anyone: I was wrong with this approach. I tried to follow a tutorial, but my data model was not appropriate for that, because I did not relate the entities to each other (linea/version), but through a third entity (producto). I'm not sure for what, but never work.

    So, I try with a different approach, guided by another thread with a similar problem: I created diferents livewire component for every entity, and I updated the corresponding component emiting an event.

    App\Livewire\Search\SelectLinea.php

    use App\Models\Lineas;
    use Livewire\Component;
    
    class SelectLinea extends Component
    {
        public $selectedLinea;
    
        public function updatedSelectedLinea($id)
        {
            $this->dispatch('lineaSelected', lineaId: $this->selectedLinea);
        }
    
        public function render()
        {
            $lineas = Lineas::all();
            return view('livewire.search.select-linea', compact('lineas'));
        }
    }
    

    App\Livewire\Search\SelectVersion.php

    use Livewire\Attributes\On;
    use Livewire\Component;
    use Illuminate\Support\Facades\DB;
    
    class SelectVersion extends Component
    {
        public $selectedLinea;
        public $selectedVersion;
    
        #[On('lineaSelected')]
        public function setLinea($lineaId)
        {
            $this->selectedLinea = $lineaId;
        }
    
        public function render()
        {
            $versiones = DB::table('productos')
            ->select(DB::raw('distinct versions.id, versions.nombre'))
            ->leftjoin('versions', 'versions.id', '=', 'productos.version_id')
            ->where('productos.linea_id', '=', $this->selectedLinea)
            ->get();
    
            return view('livewire.search.select-version', compact('versiones'));
        }
    }
    

    I created a regular blade view where combinated all livewire componentes:

    @section('content')
    <div>
        <livewire:search.select-linea></livewire:search.select-linea>
        <livewire:search.select-version></livewire:search.select-version>
    </div>
    @endsection
    

    And every component it's a different select element

    <div class="col-md-5">
        <div class="form-group">
            <select id="linea" wire:model.live="selectedLinea" class="form-control">
                <option value="" selected>---Línea---</option>
                @foreach ($lineas as $linea)
                <option wire:key="{{ $linea->id }}" value="{{ $linea->id }}">{{ $linea->nombre }}</option>
                @endforeach
            </select>
        </div>
    </div>