Stimulus: Embedded script tags prevent target detection

Created on 7 Feb 2018  路  5Comments  路  Source: hotwired/stimulus

First off, thanks for the great work so far, stimulus is a joy to use.

Not sure if this is a bug or simply a limitation of the browser (or my misunderstanding of mutation observers, or something).

As of stimulus 1.0.0, in my experience if you have a

All 5 comments

Can you share a complete snippet of HTML that illustrates the problem, please?

@javan This should do it, sorry for the messy js
https://gist.github.com/Aesthetikx/e7b2438f9ed31e269489af9ef9235bc6

Confirmed! Looks like it happens when the controller is registered before the document is complete and there are still inline <script>s to process. Stimulus returns the same (two) elements as querySelectorAll so it's not a bug with the Targets API:

connect() {
  // Both log the same elements
  console.log(this.itemTargets)
  console.log(this.element.querySelectorAll("[data-target='hello.item']"))
}

That said, I think Stimulus can probably help avoid this timing issue. In the meantime, you can avoid it by either:

  1. Moving your Stimulus setup <script> to the end of the document before </body>
  2. Moving it into a .js file loaded with <script defer> or <script async>
  3. Registering controllers when the DOM is ready or even deferring briefly:
    ```js
    addEventListener("DOMContentLoaded", event => {
    application.register("hello", controller)
    })

// Or:

setTimeout(() => {
application.register("hello", controller)
}, 1)
```
Thanks for the report!

Clearly this should be documented. In real code, you really should put the script in a separate file and not inside the HTML in the first place.

I ran into this issue while using https://github.com/ankane/chartkick which outputs the javascript inline by default. Can you release the patch?

Was this page helpful?
0 / 5 - 0 ratings