Empty state with Turbo Stream (in Rails)

I gave this question some thought and experimented a bunch.

Then I also looked at the source maps of Hey.com. It seems that they are using Stimulus to show/and the empty state of the inbox. So it’s always there, and shows when you have no new messages.

After some experimentation, I created a Stimulus controller that uses a JavaScript MutationObserver to watch changes in the tree. If there are changes I count the targets. If there are no targets I show the empty state.

index.html.erb:

<div id="vehicles" data-controller="empty-state">
  <div data-empty-state-target="emptyState">
    <%= render "empty_state" %>
  </div>
  <%= render @vehicles %>
</div>

_vehicle.html.erb: (simplified)

<div class="p-4" data-empty-state-target="item" id="<%= dom_id(vehicle) %>">
  ...
</div>

empty_state_controller.js:

import { Controller } from "stimulus";

export default class extends Controller {
  static targets = ["emptyState", "item"];

  connect() {
    this.observer = new MutationObserver(this.update.bind(this));
    this.observer.observe(this.element, {
      childList: true,
      attributes: false,
      subtree: true
    });
    this.update();
  }

  disconnect() {
    this.observer.disconnect();
  }

  update() {
    this.emptyStateTarget.classList.toggle("hidden", this.itemTargets.length !== 0);
  }
}

I hope this helps someone with this question.

2 Likes