Connected and Disconnected Target Callbacks with Stimulus
Rails Designer

Rails Designer @railsdesigner

About: I help teams around the world make their Rails apps a bit nicer to maintain and look at. 🎨 Also kickstart SaaS' in a month. 👷 And built a Rails UI Components library, used by 1000+ developers. 🚀

Location:
Amsterdam, The Netherlands
Joined:
Sep 29, 2023

Connected and Disconnected Target Callbacks with Stimulus

Publish Date: Sep 10 '24
2 1

This article was originally published on Rails Designer—UI components library for Rails app, built with ViewComponent, designed with Tailwind CSS and enhanced with Hotwire.


In a previous article I wrote about the change callbacks for the Values API. This time I want to highlight the Connect and Disconnect callbacks for targets.

A quick recap on targets: targets lets you reference important elements by name. They can be set up like so:

<div data-controller="eggs">
  <h2>Eggs</h2>

  <ul>
    <li data-eggs-target="item">🥚</li>
  </ul>
</div>
Enter fullscreen mode Exit fullscreen mode

Then in your Stimulus controller:

// app/javascript/controllers/eggs_controller.js
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = ["item"];
  // …
}
Enter fullscreen mode Exit fullscreen mode

Keep track of new targets being added

Let's assume above eggs list only allows you to add more eggs, nothing else. 🐣 The HTML could look like this:

<div data-controller="eggs">
  <h2>Eggs <span data-eggs-target="count"></span></h2>

  <ul data-eggs-target="list">
    <li data-eggs-target="item">🥚</li>
  </ul>

  <button data-action="eggs#add">Add</button>
</div>
Enter fullscreen mode Exit fullscreen mode

Let's quickly extend the above controller with the add feature:

import { Controller } from "@hotwired/stimulus"

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

  add() {
    this.listTarget.insertAdjacentHTML("beforeend", `<li data-eggs-target="item">🥚</li>`);
  }
}
Enter fullscreen mode Exit fullscreen mode

Easy enough! Let's write the code to show the number of eggs in the list.

import { Controller } from "@hotwired/stimulus"

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

  // …

  itemTargetConnected() {
    this.#updateItemCount();
  }

  itemTargetDisconnected() {
    this.#updateItemCount();
  }

  // private

  #updateItemCount() {
    this.countTarget.textContent = `(${this.itemTargets.length})`;
  }
}
Enter fullscreen mode Exit fullscreen mode

Preview of the controller, showing adding the egg-emoji to a list

Notice how the <span data-eggs-target="count"></span> gets updated with the number of eggs (targets) whenever a new one is added to the list. Also notice how it is also already updated upon the controller connect lifecycle method (ie. when the page is loaded).

Yet another small, but really useful lesser known feature of Stimulus.

Comments 1 total

  • Rails Designer
    Rails DesignerSep 3, 2024

    How have you used target callbacks? Let me know! 👇

Add comment