# Idiomatic stimulus + server-side HTML caching?

**URL:** <https://discuss.hotwired.dev/t/idiomatic-stimulus-server-side-html-caching/644>\
**Category:** General\
**Created:** [January 31, 2019, 11:36pm UTC](https://discuss.hotwired.dev/t/idiomatic-stimulus-server-side-html-caching/644 "2019-01-31T23:36:38Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![woahdae](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/woahdae/32/442_2.png) [@woahdae](https://discuss.hotwired.dev/u/woahdae)\
**Post date:** [January 31, 2019, 11:36pm UTC](https://discuss.hotwired.dev/t/idiomatic-stimulus-server-side-html-caching/644/1 "2019-01-31T23:36:38Z")

</div>

My first use-case for stimulus is refactoring a bookmarking feature on a products page where the whole product list (and most of the page) is cached server side with Russian Doll caching. So, we can’t just use inline data maps for the initial page state to indicate a user has bookmarked a product on initial load.

Previously, we had put the state of a users’ bookmark for a product in data attributes of a div just outside the products’ top-level cache statement. Then after page load, we had a bit of procedural-style jQuery that would read the special div’s data attrs and render the correct bookmark state, as well as bookmark toggle code that watches for a click, displays a spinner, and then applies the new state.

I feel like this is exactly what stimulus is made to clean up, but I’m not sure what to do with the initial page state, since it can’t be applied inline to the bookmarks HTML.

Obviously I could just keep doing what I’m doing, and read the state off a special div’s data attrs. Is there a more idiomatic way though, along the lines of data maps? “Remote data maps” or something?

Here’s an extremely simplified example.

Previously

HTML:

```
<div class="js-bookmark-state" data-bookmarked-products="123,456,789" />
<% cache do %>
  <% @products.each do |product| %>
    <div class="product" id="product-<%= product.id %>">
      <div class="product-name"><%= product.name %>
      <button class="bookmark-btn" data-bookmark-url="/path/to/bookmark" />
        <span class="bookmark-active fa fa-bookmark" style="display: none" />
        <span class="bookmark-inactive fa fa-bookmark-o" style="display: none" />
      </div>
    </div>
  <% end %>
<% end %>

```

JS:

Something that reads ‘js-bookmark-state’ to create a `bookmarkedProducts` array, then finds the correct bookmarked products and calls `$.show()` on the correct icon.

Also, watches for clicks on `.bookmark-btn`, and reads the response to similarly call `$.toggle()` on the icons if successful.

Now, using stimulus:

```
<% cache do %>
  <% @products.each do |product| %>
    <div class="product" id="product-<%= product.id %>">
      <div class="product-name"><%= product.name %>
      <button class="bookmark-btn" data-controller="bookmark" data-bookmark-url="/path/to/bookmark" data-program-id="<%= product.id %> />
        <span class="bookmark-active fa fa-bookmark" style="display: none" />
        <span class="bookmark-inactive fa fa-bookmark-o" style="display: none" />
      </div>
    </div>
  <% end %>
<% end %>

```

The stimulus `Bookmark` instance can know the `program-id` via data maps, but is the best way to track bookmarked programs via a special div?

---

<div class="post-metadata">

**Author:** ![jaredcwhite](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/jaredcwhite/32/420_2.png) [@jaredcwhite](https://discuss.hotwired.dev/u/jaredcwhite)\
**Post date:** [February 1, 2019, 7:12pm UTC](https://discuss.hotwired.dev/t/idiomatic-stimulus-server-side-html-caching/644/2 "2019-02-01T19:12:07Z")

</div>

Here’s an idea: you could create a Stimulus controller for the top-level wrapper div in your first example and use that to manage the bookmarked IDs state. Then in the child controllers for each product, use either custom events or `getControllerForElementAndIdentifier` to request state from the parent controller for a given product (or to update state).

---

<div class="post-metadata">

**Author:** ![woahdae](https://yyz1.discourse-cdn.com/flex027/user_avatar/discuss.hotwired.dev/woahdae/32/442_2.png) [@woahdae](https://discuss.hotwired.dev/u/woahdae)\
**Post date:** [February 3, 2019, 4:30pm UTC](https://discuss.hotwired.dev/t/idiomatic-stimulus-server-side-html-caching/644/3 "2019-02-03T16:30:06Z")

</div>

Thanks, yes, custom events or `getControllerForElementAndIdentifier` seems to be the way recommended here for establishing a parent-child relationship.

I actually have a different need for parent-child controllers, which I think I’ll start a new thread about, but TL;DR experience tells me to be wary of event-based control flow. `getControllerForElementAndIdentifier` would work, but what I ended up doing is if a bookmark doesn’t know it’s state, it looks it up in a data attribute elsewhere on the page, but otherwise gets and sets state like a normal controller. This way I can use the bookmark controller outside the context of a list of bookmarks, which seems well encapsulated.
