# Can't load child controller by target

**URL:** <https://discuss.hotwired.dev/t/cant-load-child-controller-by-target/381>\
**Category:** General\
**Created:** [August 15, 2018, 8:05pm UTC](https://discuss.hotwired.dev/t/cant-load-child-controller-by-target/381 "2018-08-15T20:05:33Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![imjohnbon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/imjohnbon/32/290_2.png) [@imjohnbon](https://discuss.hotwired.dev/u/imjohnbon)\
**Post date:** [August 15, 2018, 8:05pm UTC](https://discuss.hotwired.dev/t/cant-load-child-controller-by-target/381/1 "2018-08-15T20:05:33Z")

</div>

[Codepen example here](https://codepen.io/anon/pen/LBomzo?editors=1111). 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.

```
class ParentController extends Stimulus.Controller {
  static targets = ["child"];

  initialize() {    
    console.log(this.getChild(this.childTarget))
  }
  
  getChild(target) {
    return this.application.getControllerForElementAndIdentifier(target, 'multi-word-child')
  }
}

```

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.

---

<div class="post-metadata">

**Author:** ![adrienpoly](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/adrienpoly/32/78_2.png) [@adrienpoly](https://discuss.hotwired.dev/u/adrienpoly)\
**Post date:** [August 16, 2018, 9:03pm UTC](https://discuss.hotwired.dev/t/cant-load-child-controller-by-target/381/2 "2018-08-16T21:03:49Z")

</div>

@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`

https://codepen.io/adrienpoly/embed/preview/pZXqqd?height=300&slug-hash=pZXqqd&default-tabs=js,result&host=https://codepen.io&embed-version=2

---

<div class="post-metadata">

**Author:** ![imjohnbon](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/imjohnbon/32/290_2.png) [@imjohnbon](https://discuss.hotwired.dev/u/imjohnbon)\
**Post date:** [August 17, 2018, 2:50am UTC](https://discuss.hotwired.dev/t/cant-load-child-controller-by-target/381/3 "2018-08-17T02:50:48Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![javan](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/javan/32/594_2.png) [@javan](https://discuss.hotwired.dev/u/javan)\
**Post date:** [August 22, 2018, 8:42pm UTC](https://discuss.hotwired.dev/t/cant-load-child-controller-by-target/381/4 "2018-08-22T20:42:11Z")

</div>

> [@adrienpoly](#):
>
> 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

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:

```js
[ParentController, MultiWordChildController].forEach(controllerConstructor => {
  const controller = new controllerConstructor()
  this.application.controllers.push(controller)
  controller.initialize()
  controller.connect()
})

```

Your `ParentController` instance can’t find the `MultiWordChildController` instance because the `forEach` loop hasn’t gotten to its next cycle yet.

Switching the registration order would happen to fix it:

```diff
 const application = Stimulus.Application.start()
-application.register('parent', ParentController)
 application.register('multi-word-child', MultiWordChildController)
+application.register('parent', ParentController)

```

I don’t recommend relying on that as a long term fix though since it’s not documented behavior and could change.

Instead, defer accessing the child controller:

```js
initialize() {
  setTimeout(() => {
    console.log(this.getChild(this.childTarget))
  })
}

```

Or even

```js
initialize() {
  Promise.resolve().then(() => {
    console.log(this.getChild(this.childTarget))
  })
}

```
