Skip to content →

Where do I store my state in Stimulus.js?

Stimulus.js allows for a myriad of ways to store state about our webapp. One thing to always keep in mind is that Stimulus.js wants to enhance existing HTML instead of control all of the page’s DOM, so we will need to think of ways that leverage server generated HTML to manage our state and progressively enhance our page.

<head> State

Other Javascript frameworks, like Vue.js, React, and Angular, typically generate HTML on the client side, in Javascript. Stimulus relishes HTML over the wire, so much so that it doesn’t have a templating language. Since we know we are going to be dealing primarily with server generated HTML, we will try to use that as our state storage medium. One way is to store data fields in the header of the page. Since Stimulus was built to work hand in hand with Turbolinks, storing data in the HTML head section, and retrieving values we need means we don’t need a per page javascript object that will keep track of every detail. We’ve seen how you can use this when posting data to back to your Rails API. When rendering your layout, you can use the yield function to to set a placeholder for your value in the head tag, and then somewhere else, like a view for your controller, you fill in the value that will go into the head section with content_for.

Here is the Javascript function to pull meta values:

function getMetaValue(name) {
  const element = document.head.querySelector(`meta[name="${name}"]`)
  return element.getAttribute("content")
}

Here is the ruby snippet you could put in your application.html.erb:

<meta name="account-id" content="<%= content_for(:account_id) %>"/>

And here is the ruby snippet that sets the :account_id value:

<%- account_id @account.id %>

And in somewhere else in your Javascript, you would call you getMetaValue() function:

let accountId = getMetaValue("account_id")

<body> State

If you need to store data in your Stimulus controller, you can set it from html. From Stimulus’ handbook:

A Stimulus application’s state lives as attributes in the DOM; controllers themselves are largely stateless.

The tutorial on this page goes into more depth on how this is accomplished. It’s using data-* attributes on html tags inside the scope of the controller. The controller looks for these as soon as it’s created, and loads them as properties on the controller object. For example, in my tutorial on remotely updating a model from a checkbox, the controller gets the POST url from the html. This way that URL can change, and we don’t need to use any ERB inside our controller. We can also drop this controller in other parts of the app, without needing to write a new controller with a different URL.

Controller State

Finally, our controller is a Javascript object, so we can just set properties on the controller. For example, in my tutorial where we use to Stimulus to filter a list based on multiple selects, the controller has a filters property that is created on connect() and updated when any of the selection lists changes. It’s locally scoped and available in any of the functions on the controller.

Hopefully this helps you understand Stimulus.js’ philosophy on state management. It doesn’t try to be a full blown replacement for your page’s DOM, but it’s flexible enough to add immersive behavior to you web app.

Comments or Questions? Find me on twitter @jpbeatty

Want To Learn More?

Try out some more of my Stimulus.js Tutorials.

Get the next tutorial when it comes out!

Enter your email below, and you won’t miss the next Stimulus JS Tutorial

Published in ruby on rails Stimulus JS Tutorial

Comments are closed.