Related articles

No items found.
The French newsletter for Ruby on Rails developers. Find similar content for free every month in your inbox!
Register
Share:
Blog
>

StimulusJS on Rails 101

StimulusJS is the new Javascript framework that was released this year (2018) by DHH, the creator of Ruby on Rails.

This is a practical guide to start using StimulusJS in a Ruby on Rails project (with a bonus at the end 😉). You'll also find a link to a project at the end of the article that uses everything presented in this article so you can try it out right away.

You might be tempted to compare it to other frameworks like ReactJS, Angular, or VueJS but you shouldn't. StimulusJS is not playing in their field since it has no intention of building user interface components, synchronizing frontend and backend using AJAX or anything like that.

To date, the sole task of StimulusJS is about linking behaviors to HTML elements.

A real competitor would be the jQuery .on () method. jQuery is great but it requires you to define your links in Javascript files, which means you can't know if an HTML element has a linked behavior unless you read all the Javascript files. I prefer the StimulusJS approach: reading the attributes of an HTML element to know if a behavior is linked or not. Don't get me wrong, even though I delegate the linking part to StimulusJS, I still use jQuery to make my life easier when it comes to front-end development (AJAX calls, etc.). The two work well together.

A quick word about jQuery and Turbolinks

If you've already used jQuery and Turbolinks together, you'll be happy to know that there are no more:

$ (document) .ready ()

And more:

$ (document) .on ('turbolinks:load', function () {})

StimulusJS takes care of it now:) Put your code in your controllers and let the framework do the magic. Which controllers? How? Where? We're going to talk about that in a moment. First, let's install the dependencies to run StimulusJS in a Ruby on Rails project and then we'll see how to use it.

A quick word about controllers

This might be obvious to experienced front-end developers, but I want to make sure no one gets lost:

Rails has its controllers under app/controllers and StimulusJS has its controllers under app/javascript/controllers. There is no connection between them, none.

In this article, when I refer to a controller, I am talking about a StimulusJS controller.

Installing StimulusJS in Rails using Yarn and Webpacker

1. Install Yarn

Rails has moved to Yarn for managing Javascript packages. Yarn has a big community, manages dependencies, provides caching, etc. Now, when you need to add a dependency to your project (Javascript but also style sheets), I strongly suggest that you look for the Yarn package first before looking for the gem.

TL; DR: Bootstrap, MomentJS, ChartJS, Fontawesome, etc.: add them via Yarn.

To add a package, use the search box in https://yarnpkg.com/ to find it and then install it using yarn add [package name].

2. Install Webpacker

Nowadays, Rails applications don't always boil down to simple Ruby on Rails code.

You often have a Rails API, a Javascript React/vue/Angular/Younameit frontend, and a few SCSS stylesheets to make everything look nice.

In this context, we consider the Javascript front-end to be a fully-fledged application because it is often accompanied by its own controllers, routers, models, etc.

There are two things to keep in mind:

  • Keep your code base clean. Separate what is specific to your React/something UI from the rest of your application (i.e. put the JS application code in a specific subdirectory in your Rails project)
  • Take advantage of the great tools available today, such as ES6, SCSS, and more.

Webpack is there to support ES6 and SCSS compilation, minification, dependency management, and much more.

Webpacker is the gem that adds Webpack to a Rails project.

When using webpacker, a new subdirectory is added to your project: app/javascript/packs/.Each pack is a module that you can include in your views. Your StimulusJS application will be a module to include in your views (see how in the next section).

  • Add Gem 'webpacker' to your Gemfile and run Bundle Install.
  • Execute the following command: rails webpacker:install

Take a look at the following files to get an idea of what's going on:

  • config/webpacker.rb
  • config/webpack/*
  • app/javascript/packs/application.js

3. Install StimulusJS

There is a very handy command to add StimulusJS to your project:rails webpacker:install:stimulus

This will install StimulusJS, create a directory that will contain your controllers, and add a few lines to your application.js to initialize the framework.

Take a look at the following:

  • app/javascript/packs/application.js
  • app/javascript/packs/controllers/

Now get Rails to include your first pack in app/views/layouts/application.html.erb. If your pack is app/javascript/packs/application.js, then add the following:

Hello World example

Now we are ready to move on to the next topic: how to use StimulusJS.

Before going into the details of how it works, I would like you to read the following code snippet:

app/views/younameit/index.html.erb:

app/javascript/controllers/mycontroller_controller.js :

What it does is pretty simple: when you click the button, it shows “Hello World!”

Now that you have an idea of how StimulusJS works, let's break it all down.

Link an HTML element to a StimulusJS controller (data-controller)

The very first step is to link a portion of your HTML DOM to a controller.

  1. Create a controller (see example above or)
  2. Enclose the subpart of the HTML document that you want to link to this controller in an element that will have an attribute Data controller. For example: <div data-controller="mycontrollername">...</div>

That is all. Now this div and everything in it can interact with the controller Mycontrollername.

Don't fall into this trap

If your controller file name contains underscores, the corresponding name to be used in your HTML document has underscores (_) replaced by hyphens (-).

  • File name: app/javascript/controllers/content_loader_controller.js (use underscores)
  • Controller name: Content-Loader (Use Hyphens) <div data-controller="content-loader">...</div>

Data link (target data)

This is the most basic use of StimulusJS: referencing an HTML element in a controller in order to access it later. We call it a target (a target descriptor to be exact).

First, choose a name for each target and list them in the static table Targets from your controller.

Then add an attributedata-target="controllername.targetname”to each targeted HTML element.

How do I access a target from the controller? We do this by calling, for a named targetOutput:this.outputTarget.

Since in our example, the Output is a span, we can change its content via the attribute TextContent. That means that this.outputTarget.textContent = 'Call me daddy' Will display Call Me Daddy in the view.

A target for all cases

While the basic use case is a target for one HTML element, you can actually have one target for multiple HTML elements. You then access it through the table this.outputTargets (plural).

Behavior triggered by an event (data-action)

Do you want to call a method when a particular event (click, key press, etc.) occurs?

Use the attribute Data-action on your HTML element. The attribute Data-action, as you can easily guess, allows us to call a controller method on a certain event. In this example:

  • The event is Click
  • The controller is Mycontroller
  • The method to call is Say_Hello

You can listen to numerous events like click, dbclick, keyup, etc.

Initialize your controller from the view (data-*)

Sometimes you want to reuse the same controller multiple times in the same view for different items (a different controller instance for each item).

Let's say we have a blog with comments. Abusive comments can be reported to the administrator. Each comment should be displayed and have its own report button. The report must be asynchronous (AJAX).

It's obvious that we only need one StimulusJS controller to provide this simple behavior: catch a button click event and call a controller method that will make all the necessary AJAX calls to report the abusive comment. Each comment can then be linked to a different instance of the controller.

Since we can't send an argument in Data-action (<button data-action="click->comment-report#report(41)">...</button> doesn't work), we need to figure out how to initialize each instance with the comment id so that the AJAX call is done at the right url.

Again, it's very simple: when using the function Data controller in an HTML element, you can also add other attributes Data- <controller name>- <attribute name>. For example data-comment-report-comment-id="42":

Note that data-comment-report-comment-id Use lowercase words separated by hyphens while this.data.get (“commentID”)uses CamelCase lowercase syntax.

To summarize

There are three main tools:

  • Data controller : if your controller file is named progress_tracker_controller.js, you do <div data-controller="progress-tracker">...</div>
  • Data-Target : for one Name target in your controller, you do <div data-controller="progress-tracker"><p data-target="progress-tracker.name"></p></div> and access it using this.nameTarget.
  • Data-action : call the method Rule_them_all When an event of Click occurs by adding said method to the controller and <div data-controller="progress-tracker"><p data-action="click->progress-tracker#rule_them_all">Click me</p></div>

There are also these 3 methods that I'm not going to discuss in this article, just note that they exist and that they can come in handy once you get familiar with StimulusJS and need to do more advanced things.

  • initialize ()is invoked once, when the controller is instantiated for the first time.
  • connect (): is invoked every time the controller is connected to the DOM.
  • disconnect (): is invoked every time the controller is disconnected from the DOM.

From there, you can do just about anything you want. You can import jQuery into your controller and make AJAX calls, change the style of an element, etc. In fact, you delegate the link and event management part to StimulusJS and you do the rest with the tools of your choice. You can even skip the target part and use the jQuery selectors, but why bother when StimulusJS does it for you?

Bonus: Add StimulusJS to ActiveAdmin

If you need to offer a better user experience on your ActiveAdmin dashboard, I suggest adding a little sugar to it by using Stimulus. The principle is the same: views, controllers, data-*.

We saw how to include a pack in a view layout using javascript_pack_tag, but how do you include it in ActiveAdmin?

Open config/initializers/active_admin.rband add the following:

That's it for the configuration part! Here is a basic example for using it in a form:

One thing you might notice is that you need to reboot your Rails server for any controller changes to take effect. This is because webpack is only compiled once, when the application is started.

One way to correct this is to remove lines added to config/initializers/active_admin.rb and simply add src script: asset_pack_path ('application.js') to each ActiveAdmin form that uses a StimulusJS controller:

Clone this Github repository and start playing with StimulusJS!

Thanks for reading!