How to Pass Data from a Rails view to Stimulus: A Simple Guide

How to Pass Data from a Rails view to Stimulus: A Simple Guide

·

3 min read

Everyone talks about the importance of pulling data from endpoints, but what if you already have your data on the page and want to pass it directly to your Stimulus controller? Here’s an efficient method of passing data to Stimulus!

The Problem

I have a page that has a bunch of modals on it that the user can open to see more details.

User can click ‘More…’ and get a modal

User can click ‘More…’ and get a modal

But we already have the details when we render the page. We just use some of them to produce this summary block. The rest are there, but unused.

In the modal, we want to present a Tabulator table. With Tabulator you have many options to get data into the view. Most people would say, fine, just load the data from an endpoint when the user opens a modal.

But I already have the data, why call the server again?

The Solution: Passing Data to Stimulus Directly

Here’s my Stimulus controller for my table

import { Controller } from "@hotwired/stimulus";

// Connects to data-controller="pc-period-details-table"
export default class extends Controller {
  static targets = ["table"];

  connect() {
    this.tabulatorTable = new Tabulator(this.tableTarget, {
      height: "311px",
      dataTree: true,
      dataTreeStartExpanded: false,
      columns: [
        { title: "Name", field: "lineItemName", width: 200 },
        { title: "Notes", field: "lineNotes", width: 150 },
        { title: "Value", field: "lineValue", width: 150 }
      ],
    });
  }
}

In my partial, I already have the data in a local variable called base_data.

I found a very simple trick to get that data from the view into Stimulus as a JSON object.

Here’s the view

       <div class="small periodDetails">
          <div id="example-table" data-controller="pc-period-details-table" 
          data-pc-period-details-table-target="table" 
          data-pc-period-details-table-data-value="<%=base_data.to_json%>"></div>
        </div>

We do the following:

  1. Connect the div to the Stimulus controller using data-controller

  2. Set ourselves as a target. Ok, I don’t technically need to do this. I could use this.element in the controller. I just prefer this way.

  3. Pass our data up to the controller as a value by called to_json on the data.

We can update the Stimulus controller to look like this:

import { Controller } from "@hotwired/stimulus";

// Connects to data-controller="pc-period-details-table"
export default class extends Controller {
  static targets = ["table"];

  static values = {
    data: Object
  };

  connect() {
    this.tabulatorTable = new Tabulator(this.tableTarget, {
      height: "311px",
      data: this.dataValue,
      dataTree: true,
      dataTreeStartExpanded: false,
      columns: [
        { title: "Name", field: "lineItemName", width: 200 },
        { title: "Notes", field: "lineNotes", width: 150 },
        { title: "Value", field: "lineValue", width: 150 }
      ],
    });
  }
}

Now our modal will render with the table and the same data that we had on the page.

In conclusion, it’s quite clear that passing data directly to your Stimulus controller instead of pulling it from endpoints can provide an efficient alternative, especially when you already have the required data on your page. Implementing this method can eliminate unnecessary server calls, improving the performance of your application. If you’re seeking to enhance your knowledge of Stimulus and the many ways you can interact with data, mastering this method of passing data to Stimulus is a step in the right direction. Remember, there’s more than one way to approach a problem, and finding the most optimal solution often requires exploring a variety of strategies.

As usual, I am writing this here mainly to cement it in my own brain. But I couldn’t find any examples of this online, so hopefully this benefits someone else!

You can find me on Twitter where I talk about Ruby on Rails, my company Zonmaster, and life in general. If you’re looking for help with your Rails project drop me a note on Twitter or LinkedIn