Open brydave opened 1 year ago
After further exploration, I'll also add that the syntax for a more specific,broadcast_redirect_to
method, seems nice and concise. But, I'd love to hear if anyone has any other recommendations.
class ImportJob < ApplicationJob
def perform(import)
# process import
@import.broadcast_redirect_to "loading-state", url: my_redirect_url, turbo_action: "replace"
end
end
// same JavaScript
import { StreamActions } from "@hotwired/turbo"
StreamActions.redirect_to = function() {
const content = this.querySelector("template").content
const url = content.querySelector("div[url]").getAttribute("url")
const turboAction = content.querySelector("div[turbo-action]").getAttribute("turbo-action")
Turbo.visit(url, { action: turboAction })
}
Here are the brodcastable modules I added to an initializer to get it working:
module Turbo::Streams::Broadcasts
def broadcast_redirect_to(*streamables, url:, turbo_action:)
broadcast_stream_to(streamables, content: turbo_stream_action_tag(:redirect_to, url: url, "turbo-action": turbo_action))
end
end
module Turbo::Broadcastable
def broadcast_redirect_to(*streamables, url:, turbo_action: "advance")
Turbo::StreamsChannel.broadcast_redirect_to(streamables, url: url, turbo_action: turbo_action)
end
end
As far as I can tell, and I could totally be missing something, it seems like there's no direct way to send attributes to a turbo-stream tag via a broadcastable method without using a partial or HTML content. Here's a scenario:
Imagine importing data in a background job. You want to display a loading page and then redirect when the import is complete using a custom turbo action.
To achieve this currently, I think I have to:
This should work, but a more streamlined approach might be to add HTML attributes directly to the broadcasted tag without having to send a partial. It might also integrate nicely with custom turbo stream actions.
To get this working, I created a custom
broadcast_custom_action_to
method, which allows attributes to be applied directly on theturbo_stream_action_tag
and has a default turbo_stream rendering. But I'm not sure if this is the best practice.Is there a more efficient or recommended way to enhance broadcastable methods?
Here's an example of the existing implementation:
And here's an example of the
broadcast_custom_action_to
method that doesn't require an arbitrary partial, and applies theattributes
to theturbo-stream
tag itself.To implement the custom action, here's how I expanded the broadcasts and broadcastable modules:
Hopefully that makes sense, but I'm happy to clarify anything!