SvelteOnRails::ActionCable
Setup
Add app/channels/svelte_on_rails_channel.rb
class SvelteOnRailsChannel < ApplicationCable::Channel
def subscribed
stream_from "svelte_on_rails_channel"
end
def unsubscribed
# Any cleanup needed when channel is unsubscribed
end
end
config
action_cable:
channel: "svelte_on_rails_channel"
javascript
npm i @rails/actioncable
Add to application.js
import { createConsumer } from "@rails/actioncable"
import { SvelteOnRails, dispatchSvelteStreamEvent, streamDebugLog } from '@csedl/svelte-on-rails'
SvelteOnRails.debug = true
window.addEventListener('load', () => {
setTimeout(() => {
const consumer = createConsumer()
consumer.subscriptions.create("SvelteOnRailsChannel", {
connected() {
streamDebugLog("Connected to SvelteOnRailsChannel")
},
disconnected() {
streamDebugLog("Disconnected from SvelteOnRailsChannel")
},
received(data) {
streamDebugLog("Received:", data)
dispatchSvelteStreamEvent(data)
}})
}, 100) // or 300-500 if 100 not enough
})
What dispatchSvelteStreamEvent does
- Without the attribute
componentgiven, it searches for all elements with the classsvelte-componentand fires the eventchannel-action- When
selectoris given, it searches for all matching elements within each component. - The event can be overriden by the argument
event
- When
Usage
app/frontend/javascript/components/folder/MyComponent.svelte
<script>
import {addComponentStreamListener} from '@csedl/svelte-on-rails/src/componentStreamListener'
function handleCableEvent(event) {
console.log('Event received by Turbo Stream', event.detail)
}
</script>
<!--on ANY element:-->
<h1 use:addComponentStreamListener={handleCableEvent}>Test TurboStreams Channel</h1>
The addComponentStreamListener adds the eventListener stream-action on the wrapping Element. The «wrapping Element» is the Element from the view helper svelte with the class svelte-component.
Now you can dispatch events on the component by:
SvelteOnRails::ActionCable.dispatch(
'folder/MyComponent',
{ message: "greetings from Server: äöü🤣🌴🌍漢字" }
)
And you will find the object, with the message key on the browser logs.
Without any arguments, just by SvelteOnRails::ActionCable.dispatch it would fire the stream-action event on all components.
The #dispatch_by_selector does not go over the component, it searches for any matching selector just on the whole document and fires the given event there.