useDispatch
Adds a dispatch helper function to emit custom events. Useful to communicate between different controllers.
!> Deprecated: useDispatch() is deprecated. Please use the built-in this.dispatch() function from Stimulus: https://stimulus.hotwired.dev/reference/controllers#cross-controller-coordination-with-events
Migration guide
Because the dispatch() function from Stimulus is very similar, the migration process to the Stimulus version of dispatch() should be fairly simple:
- remove the
useDispatchimport - remove the
useDispatchinitializer - wrap your payload in a
detailobject
import { Controller } from '@hotwired/stimulus' - import { useDispatch } from 'stimulus-use' export default class extends Controller { connect() { - useDispatch(this) } add() { - this.dispatch('add', { quantity: 1 }) + this.dispatch('add', { detail: { quantity: 1 } }) } }
Reference
Mixin
useDispatch(controller, options = {})
controller : a Stimulus Controller (usually 'this')
options :
| Option | Description | Default value |
|---|---|---|
element |
The element the event will be emitted from. | The controller element |
eventPrefix |
Whether to prefix or not the emitted event. Can be a boolean or a string. - true prefix the event with the controller identifier item:add - someString prefix the event with the given string someString:add - false to remove prefix |
true |
bubbles |
Whether the event should bubble. | true |
cancelable |
Whether the event is cancelable. | true |
debug |
Whether to log debug information. See debug for more information on the debugging tools | false |
The dispatch function
Once the useDispatch mixin is applied, your controller has a new this.dispatch function available you may use to emit custom events.
dispatch(eventName, detail = {})
| Param | Description |
|---|---|
eventName |
a mandatory string for the name of the event to emit. |
detail |
A payload object that will be passed through the event and available for the receiver with event.detail |
Usage
// item_controller.js import { Controller } from '@hotwired/stimulus' import { useDispatch } from 'stimulus-use' export default class extends Controller { connect() { useDispatch(this) } add() { // dispatch a custom event item:add this.dispatch("add") } }
Bubbling events
The emitted event sent by the dispatch function will bubble up the tree of the DOM.
Therefore all parent elements can listen to it directly.
<div data-controller="reciever" data-action="emitter:add->reciever#update"> <div data-controller="emitter" data-action="click->emitter#add" ></div> </div>
If both are at the same level or if the reciever controller is even nested within the controller, you should listen to event with @window to catch it.
<div data-controller="reciever" data-action="emitter:add@window->reciever#update"></div> <div data-controller="emitter" data-action="click->emitter#add" ></div>
Example building a cart counter with the dispatch helper
The HTML markup. See the custom event item:add that the cart controller is listening to
<div data-controller="cart" data-action="item:add->cart#refreshTotal" data-cart-counter="0"> <button data-controller="item" data-action="item#add"> Add </button> <div> <span>No of items : </span> <span data-cart-target="counterView">0</span> </div> </div>
The item controller dispatching the event
//item_controller.js import { useDispatch } from 'stimulus-use' export default class extends Controller { connect() { useDispatch(this) } add() { this.dispatch('add', { quantity: 1 }) } }
The cart controller receiving the event
//cart_controller.js import { ApplicationController } from 'stimulus-use' export default class extends ApplicationController { static targets = ['counterView'] refreshTotal(e) { this.counter += e.detail.quantity console.log(e.detail.controller) // the emitting item_controller } renderCounter() { this.counterViewTarget.textContent = this.counter } set counter(value) { this.data.set('counter', value) this.renderCounter() } get counter() { return this.data.get('counter') } }