Integrate stimulus with websockets


Hey I was wondering what was the best way to integrate stimulus with websockets
What I am currently doing is that I have a websocket with some javascript updating the controller html attribute and I have the stimulus controller refreshing with a timer.

Here are my questions.

  • I see there are onlick, onsubmit handlers, are there other handlers ? (can you add some ? typically when my websocket receives new data I would like to trigger an event to refresh the element)

  • Is there a way to re-initialize the element ? or maybe deconnect it and reconnect it. Just thinking out loud here.

(detail, I’m using phoenix with elixir, but I think this is applicable for any other backend framework that supports websockets)


Ok here is what I ended up doing in case it can help anybody

  • my websocket code is now firing an “update” event on update
  • The controller is listening to that update event and re-rendering the UI accordingly.

Here is what the code look like

channel.on('update', ({lastSyncedAt}) => {
    // this update is used on several elements with various controllers, so I need to get the controller name 
    // to update the proper attribute
    const constrollerName = elementToUpdate.getAttribute('data-controller');
    elementToUpdate.setAttribute(`data-${constrollerName}-last-synced-at`, lastSyncedAt);
   // I fire an "update" event on the element
    const updateEvent = new Event('update');
          class="media-body trading_account_last_synced_at"
          data-url-hash="<%= url_hash %>"
          <-- Here is where I am hooked up to the update event -->
          <-- this is the element I update with my websocket -->
          data-main-sidebar-trading-account-last-synced-at="<%= last_synced_at %>"
          <span class="media-heading text-semibold"><%= name %></span>
          <span class="text-muted">
              class="icon-checkmark3 text-size-small text-success"
              style="margin-top: -1px; font-size: 13px;"
              <%= account_number %>

hopefully the code is clear enough, let me know if anything doesn’t make sense


digging into javascript api, I have made a little update to the code.
It turns out that by using CustomEvent, your events can have value. So with the websocket I just fire a custom event and let the controller take care of the update.
Here is how the code looks now.

channel.on('update', ({lastSyncedAt}) => {
    const updateEvent = new CustomEvent('update', {detail: lastSyncedAt});

and the js controller is now just

set lastSyncedAt(value) {
    return'last-synced-at', value);

update({detail}) {
    this.lastSyncedAt = detail;;

and I just changed the event handler on the html so now


the weird variable naming detail, comes from the CustomEvent api, you can only pass an object with a detail attribute.
Hope this helps someone