I've upgraded from Rails 6 to 7 and now my action cable channels are not listening anymore. I'm sure it's a silly mistake but for the life of me I cannot track it down.
app/javascript/channels/consumer.js
import { createConsumer } from "@rails/actioncable"
export default createConsumer()
app/javascript/channels/settings_channel.js
import consumer from "./consumer"
consumer.subscriptions.create({ channel: "SettingsChannel" })
document.addEventListener('turbo:load', () => {
//console.log(attendance_id);
consumer.subscriptions.create({ channel: "SettingsChannel"}, {
connected() {
console.log("connected to settings channel ");
},
disconnected() {
// Called when the subscription has been terminated by the server
},
received(data) {
console.log("settings channel data:");
console.log(data);
if(data.tab){
//clear other selected tabs first then highlight selected ones.
const actions_tab = document.getElementById('actions-tab');
if(actions_tab){
actions_tab.classList.remove('settings-active-tab','settings-inactive-tab');
if(data.tab == 'actions'){
actions_tab.classList.add('settings-active-tab');
}else{
actions_tab.classList.add('settings-inactive-tab');
}
}
const committees_tab = document.getElementById('committees-tab');
if(committees_tab){
committees_tab.classList.remove('settings-active-tab','settings-inactive-tab');
if(data.tab == 'committees'){
committees_tab.classList.add('settings-active-tab');
}else{
committees_tab.classList.add('settings-inactive-tab');
}
}
const members_tab = document.getElementById('members-tab');
if(members_tab){
members_tab.classList.remove('settings-active-tab','settings-inactive-tab');
if(data.tab == 'members'){
members_tab.classList.add('settings-active-tab');
}else{
members_tab.classList.add('settings-inactive-tab');
}
}
const motions_tab = document.getElementById('motions-tab');
if(motions_tab){
motions_tab.classList.remove('settings-active-tab','settings-inactive-tab');
if(data.tab == 'motions'){
motions_tab.classList.add('settings-active-tab');
}else{
motions_tab.classList.add('settings-inactive-tab');
}
}
const session_tab = document.getElementById('session-tab');
if(session_tab){
session_tab.classList.remove('settings-active-tab','settings-inactive-tab');
if(data.tab == 'session'){
session_tab.classList.add('settings-active-tab');
}else{
session_tab.classList.add('settings-inactive-tab');
}
}
const system_tab = document.getElementById('system-tab');
if(system_tab){
system_tab.classList.remove('settings-active-tab','settings-inactive-tab');
if(data.tab == 'system'){
system_tab.classList.add('settings-active-tab');
}else{
system_tab.classList.add('settings-inactive-tab');
}
}
}
//end of inserted code for data received
}
});
})
app/javacript/application.js
import "@hotwired/turbo-rails"
//below is not supported yet
//import "@hotwired/stimulus-importmap-autoloader"
import "./controllers"
import "@rails/actioncable"
import "@rails/activestorage"
import "./channels"
import Rails from "@rails/ujs"
window.Rails = Rails;
if(Rails.fire(document, "rails:attachBindings")){
Rails.start();
}
app/config/importmap.rb
# Pin npm packages by running ./bin/importmap
pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
#pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
# Use libraries available via the asset pipeline (locally or via gems). # Rails 7.0 required
pin "@rails/actioncable", to: "actioncable.esm.js"
pin "@rails/activestorage", to: "activestorage.esm.js"
Thanks in advance for any advice! I had this working well with turbolinks in Rails 6 :-/
Solved it!
My issue was within channels/index.js
By default rails 7 ships with the following code in channels/index.js
const channels = require.context('.', true, /_channel\.js$/)
channels.keys().forEach(channels)
this code is meant to automatically import all *_channel.js files. Problem is this is NOT supported in stimulus yet (for channels and controllers)...see this thread: https://github.com/hotwired/stimulus-rails/issues/73
So my solution was to load them manually until the auto loading is supported.
Here's the new code in channels/index.js:
import "./settings_channel"
import "./vote_channel"
import "./member_vote_channel"
import "./attendance_channel"