Dealing with Symfony 7 project that it use Hotwire technologies (Stimulus, Turbo), I'm facing with strange issue with my Stimulus controller.
I have a target controller Stimulus that recognize onto connect() function lifecycle BUT not onto the initialize() controller lifecycle.
The Stimulus controller :
export default class Autocomplete extends Controller
{
static targets = ["input", "hidden", "results"]
static classes = ["selected"]
static values = {
ready: Boolean,
submitOnEnter: Boolean,
url: String,
minLength: Number,
delay: { type: Number, default: 300 },
queryParam: { type: String, default: "q" },
}
static uniqOptionId = 0
connect() {
console.log(this.targets.find("input")) // OK
console.log(this.targets.find("results")) // OK
the HTML DOM objects :
<div data-controller="autocomplete" class="ms-auto">
<div data-controller="autocomplete" data-autocomplete-url-value="{{ path('app_fo_search') }}" role="combobox">
<div class="input-group input-group-sm">
<input type="text" id="search_input" class="form-control form-control-sm collapse collapse-horizontal" placeholder="Rechercher un artiste, une oeuvre ou une collection...." data-autocomplete-target="input"/>
<span class="input-group-text" data-bs-toggle="collapse" data-bs-target="#search_input"><i class="bi bi-search"></i></span>
</div>
<input type="hidden" name="search" id="search_value" data-autocomplete-target="hidden"/>
<ul class="list-group" data-autocomplete-target="results" style="min-width: calc(25% - 8px);max-width:calc(33% - 8px);max-height: 90vh; overflow-y: scroll;position: absolute;right:1rem;z-index: 10000;"></ul>
</div>
</div>
Browser inspector error :
You have nested your automplete
controllers. There is no need for that here. The outer controller doesn't have access to nested targets. Note, that this applies only if it is the same controller, different controllers can be nested without interference.
When nested, each controller is only aware of its own scope excluding the scope of any controllers nested within.
https://stimulus.hotwired.dev/reference/controllers#nested-scopes
You should use connect()
whenever you want to access DOM:
initialize() // Once, when the controller is first instantiated
connect() // Anytime the controller is connected to the DOM
https://stimulus.hotwired.dev/reference/lifecycle-callbacks#methods
You can also use predefined target properties instead this.inputTarget
, this.resultsTarget
: