12

I'm currently on Rails 6.0.4 and I want to use Stimulus to build a new page. There's a lot of work still to do before upgrading to Rails 7, so I want to use importmaps and stimulus with Rails 6 if possible. But so far I haven't been able to get a stimulus controller working. I followed these steps:

1. Update the Gemfile and bundle:

gem 'importmap-rails'
gem 'stimulus-rails'

2. Run rails importmap:install

This gave me config/importmap.rb, and app/javascript/application.js, which was pinned as "application" in the config file.

3. Rename the current application.js file

My current application.js is inside app/assets/application.js.coffee, so I renamed this to old_application.js.coffee for the time being and updated application.html.haml to the following:

= javascript_include_tag "old_application", defer: true
= javascript_importmap_tags

This seemed to work and it gave me the following import map when I rendered the page:

{
  "imports": {
    "application": "/assets/application-920fceca960b509c1e98c9b27d167fa368d4b588ceb1be42d1667552714f94d5.js"
  }
}

4.Run rails stimulus:install

This gave me the app/javascript/controllers folder with index.js, application.js and hello_controller.js inside.

It also updated config/importmap.rb to the following:

pin "application", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"

... and my app/javascript/application.js to the following:

import "controllers"

This then gives me an error, saying that controllers/hello_controller.js has not been precompiled:

AssetNotPrecompiled Error

5. Update asset paths and precompiled files

We're on version 3 of sprockets, and upgrading to version 4 will also take some time, due to this issue. So instead I updated the existing initializers/assets.rb file to include the new javascript folder and files:

Rails.application.config.assets.paths << Rails.root.join('app', 'javascript', 'controllers')
Rails.application.config.assets.precompile += ['application.js', 'controllers/index.js', 'controllers/application.js', 'controllers/hello_controller.js']

This fixed the issue and gives me the following import map on the rendered page:

{
  "imports": {
    "application": "/assets/application-920fceca960b509c1e98c9b27d167fa368d4b588ceb1be42d1667552714f94d5.js",
    "@hotwired/stimulus": "/assets/stimulus.min-c5a29ae8ade968ede2149a7e76a29d0756a87cef66959113681098e5923ba26b.js",
    "@hotwired/stimulus-loading": "/assets/stimulus-loading-6b29b7e0382bd421ac62df99b46f45072fd3962208fbf0b2522041b4d037bbd9.js",
    "controllers/hello_controller": "/assets/hello_controller-8cddac086717993eeda2cc8af3be73bc3a6ecfb07212600aeed8ce8122fffa34.js",
    "controllers": "/assets/index-7445df4dc00776a5e3496034da4bc5906891c342c89c0e6a7775b1498b8222d8.js",
    "controllers/application": "/assets/application-5703baa647baaa5a3da21d4e61aa5686824d0e0ab82c2ba11f5c963cc8414a8f.js"
  }
}

6. Test stimulus controller with an alert

I changed hello_controller.js to show an alert when it's connected:

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    alert('Hello World!')
  }
}

But when I attach this to an element with data-controller="hello" I don't see anything, suggesting that stimulus hasn't been correctly loaded.

This is the partial for that:

.home-container{data: { controller: 'hello' }}
  %section
    .container

Which gives me this HTML:

<div class="home-container" data-controller="hello">
  <section>
    <div class="container">
    </div>
  </section>
<div>

Can anyone suggest what I might be missing? If I start a new rails app on Rails 7 and set everything up like that, it works without a problem.

2
  • Can you share the view or partial with the data-controller='hello' to the question? Commented Feb 2, 2022 at 17:58
  • @JoeThor yes I've updated the post with that partial, and the HTML it generates. Thanks Commented Feb 3, 2022 at 10:07

1 Answer 1

7

I was experiencing the same issue. Running rails assets:clean and rails assets:clobber solved the issue for me. Sorry, I do not remember which one did the trick, as I was applying the clueless dog approach.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.