StimulusJS: Finding out the state of other controllers

So last night, I had to find out the state of another controller in Eager.app, help desk and customer service platform built on a Rails monolith.

I recalled a few months ago reading this on Github as a way to find out the state of another controller: https://github.com/stimulusjs/stimulus/issues/35

This is great, but inspiration struck tonight and I stumbled upon a new (and I believe, more elegant) way of finding out the state of other StimulusJS controllers: callbacks.

Let’s take a look at some code…

Here are two controllers:

  1. dashboard_controller.js

  2. sidebar_controller.js

Imagine the sidebar controller wanted to know the state of the dashboard controller. Let’s set some data in the dashboard controller:

// dashboard_controller.js

import { Controller } from "stimulus"

export default class extends Controller {
  connect() {
    this.name = "Simon"
  }
}

And let’s say in the sidebar controller I wanted to find out that name. Let’s take a look a look at how we would do that with callbacks.

First, I’m going to set an event listener within the dashboard controller. I’ll be using jQuery for simplicity’s sake, but this would work with plain vanilla JS as well.

// dashboard_controller.js

import { Controller } from "stimulus"

export default class extends Controller {  
  connect() {
    this.name = "Simon"

    $(document).on('dashboard.state', function(event, callback) {
  callback(this)
}.bind(this))
  }
}

Alright, you can begin to see what we’re about to do. In the sidebar_controller.js file, we’ll do this:

// sidebar_controller.js

import { Controller } from "stimulus"

export default class extends Controller {  
  getDashboardState() {
    $(document).trigger('dashboard.state', function(dashboardState) {
  // Your code to handle the state
})
  }
}

And that’s it!

By using a callback, you can ping another controller for their state and the state will return itself, allowing you to perform some action.

Notice some problems with my code? Let me know on Twitter @geetfun.