# Parent-Child Controllers for Stimulus

**URL:** <https://discuss.hotwired.dev/t/parent-child-controllers-for-stimulus/1890>\
**Category:** General\
**Created:** [January 6, 2021, 6:07pm UTC](https://discuss.hotwired.dev/t/parent-child-controllers-for-stimulus/1890 "2021-01-06T18:07:24Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![toddkummer](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/toddkummer/32/1379_2.png) [@toddkummer](https://discuss.hotwired.dev/u/toddkummer)\
**Post date:** [January 6, 2021, 6:07pm UTC](https://discuss.hotwired.dev/t/parent-child-controllers-for-stimulus/1890/1 "2021-01-06T18:07:24Z")

</div>

There are a couple of solutions for communicating between controllers, but each time I reach for Stimulus I find myself wanting to be able to compose controllers. This approach follows the declarative nature of targets, classes and values. Declare the parent and children and it will be so.

Here is a [fork with the feature](https://github.com/toddkummer/stimulus/wiki/Parent-Child-Controllers-for-Stimulus), including [instructions on how to try it out](https://github.com/toddkummer/stimulus/wiki/How-to-Try-It-Out-from-GitHub) from GitHub.

* * *

## Definitions

Define `parent` and `children` names in your controller using static properties. Only one parent can be defined per controller.

```auto
// controllers/search_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static children = ['searchResult']
  // …
}

// controllers/search_result_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static parent = ['search']
  // …
}

```

## Properties

For each child name defined in the `static children` array, the following properties are added to your controller, where `[name]` corresponds to the child’s name:

| Kind | Name | Value |
| --- | --- | --- |
| Singuluar | this.[name]Child | The first matching child |
| Plural | this.[name]Children | An array of the children |

The parent is available as `this.parent` regardless of the name specified.

## Naming Conventions

Always use camelCase to specify parent and child names, since they map directly to properties on your controller. The names must match the controller identifier of the related controller.

For example, if the child the SearchResultController, then the identifier of the controller in the html is `search-result` and the child name is `searchResult`.

## Callbacks

Before and after callbacks are available for the registration of both parent and child controllers.

To perform logic when a child is registered with a parent component, define either of the following methods on the parent, where `[name]` corresponds to the child’s name:

- `before[name]ChildRegistration(childController)`
- `after[name]ChildRegistration(childController)`

To perform logic when a parent is registered with a child component, define either of the following methods on the child:

- `beforeParentRegistration(parentController)`
- `afterParentRegistration(parentController)`

---

<div class="post-metadata">

**Author:** ![toddkummer](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/toddkummer/32/1379_2.png) [@toddkummer](https://discuss.hotwired.dev/u/toddkummer)\
**Post date:** [January 15, 2021, 10:13pm UTC](https://discuss.hotwired.dev/t/parent-child-controllers-for-stimulus/1890/2 "2021-01-15T22:13:38Z")

</div>

I added the sibling controllers, but my update to the wiki entry broke the link above. Here is [the updated wiki link for Related Controllers](https://github.com/toddkummer/stimulus/wiki/Related-Controllers-for-Stimulus).

I’m also starting to question using links to a wiki that change when the title is changed, so here’s a [link to the branch with the changes](https://github.com/hotwired/stimulus/compare/main...toddkummer:relationships).
