Codepen example here. If you open that up and look at the console, you’ll see “null” is the first thing that gets output to the console (when it should be a controller).
I’m pretty confused as to why this is not working. In my example, I have a simple structure of a controller with a nested controller inside of it:
<div data-controller="parent">
<div data-controller="multi-word-child" data-target="parent.child">
Some text
</div>
</div>
As you can see, we have a “parent” controller, as well as a nested controller (“multi-word-child”) that is also a target of the “parent” controller.
In the initialize method of the “parent” controller, I have code that uses getControllerForElementAndIdentifier in an attempt to get the “multi-word-child” controller by passing in the “parent.child” target as well as the controller name.
For some reason though, the console.log() above returns null. Does anyone have any insight? I’m fairly lost here. In my “actual” code it’s even weirder, sometimes it works depending on the name of the child controller. Seems very obscure.
@imjohnbon I think your are having a racing issue.
Controllers are evaluated by stimulus from top to bottom of the document. So when Parent controller initializes, children controllers are not yet initialized so they are not visible within the application context and cannot be found by getControllerForElementAndIdentifier().
here is a modified version of your codepen. If you click on the text you will see that the function getChild() works perfectly but it is called too soon in connect/initialize
That would make sense. I was wondering if it was a race condition earlier considering how strange it was. Makes me wish there was some kind of initialize like function that ran once all the initial controllers on the page were fully loaded. Thanks for the help!
That’s mostly true. Both controllers are initialized synchronously because they appear in the DOM at the same time. Here’s a very simplified of what Stimulus does: