1

I am trying to build a chat feature in my app and initially, the action cable had worked for it seems like it is not getting any data to broadcast. I have tried to console log in the chatroom_channel.js but the "data" is not being populated on the console.

initChatroomChannel is also exported from application.js

I have also tried to use the solution from the ticket below but that also did not help out.

ActionCable Not Receiving Data

There's are the related files.

Thank you Onur

messages_controller

class MessagesController < ApplicationController
  def create
    @chatroom = Chatroom.find(params[:chatroom_id])
    @message = Message.new(message_params)
    @message.chatroom = @chatroom
    @message.user = current_user
    if @message.save

      ChatroomChannel.broadcast_to(
        @chatroom,
        render_to_string(partial: "message", locals: { message: @message })
    )

      redirect_to chatroom_path(@chatroom, anchor: "message-#{@message.id}")
    else
      render "chatrooms/show"
    end
  end

  def message_params
    params.require(:message).permit(:content)
  end

chatrooms_controller

class ChatroomsController < ApplicationController
  def index
    @chatrooms = []
    all_chatrooms = Chatroom.all
    all_chatrooms.each do |chatroom|
      @chatrooms << chatroom if (current_user.id == chatroom.engager_id || current_user.id == chatroom.receiver_id)
    end
  end

  def show
    chat = Chatroom.find(params[:id])
    if (current_user.id == chat.engager_id || current_user.id == chat.receiver_id)
      @message = Message.new
      @chatroom = chat
    else
      redirect_to chatrooms_path
    end
  end

  def destroy
    @chatroom = Chatroom.find(params[:id])
    @chatroom.destroy

    redirect_to chatrooms_path
  end
end

chatroom_channel.rb

class ChatroomChannel < ApplicationCable::Channel
  def subscribed
    # stream_from "some_channel"
    chatroom = Chatroom.find(params[:id])
    stream_for chatroom
  end

  # def unsubscribed
  #   # Any cleanup needed when channel is unsubscribed
  # end
end

chatroom_channel.js


import consumer from "./consumer";

const initChatroomCable = () => {
  const messagesContainer = document.getElementById('messages');
  if (messagesContainer) {
    const id = messagesContainer.dataset.chatroomId;

    consumer.subscriptions.create({ channel: "ChatroomChannel", id: id }, {
      received(data) {
        console.log(data)
        messagesContainer.insertAdjacentHTML("beforeend", data)
      },
    });
  }
}

export { initChatroomCable };

application.js

import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"


Rails.start()
Turbolinks.start()
ActiveStorage.start()



// External imports
import "bootstrap";
import { loadDynamicBannerText } from '../componets/banner';

// Internal imports, e.g:
import { initChatroomCable } from '../channels/chatroom_channel';

document.addEventListener('turbolinks:load', () => {

  initChatroomCable();

  jQuery.fn.carousel.Constructor.TRANSITION_DURATION = 2000
  var $item = $('.carousel-item');
  var $wHeight = $(window).height();
  $item.eq(0).addClass('active');
  $item.height($wHeight * 0.75);
  $item.addClass('full-screen');

  $('.carousel img').each(function () {
    var $src = $(this).attr('src');
    var $color = $(this).attr('data-color');
    $(this).parent().css({
      'background-image': 'url(' + $src + ')',
      'background-color': $color
    });
    $(this).remove();
  });

  $(window).on('resize', function () {
    $wHeight = $(window).height();
    $item.height($wHeight * 0.75);
  });

  $('.carousel').carousel({
    interval: 6000,
    pause: "false"
  });

  const banner = document.getElementById("banner-typed-text")
  if (banner) {
    loadDynamicBannerText();
  }
});

import "controllers"

_message.html.erb


<div class="message-container" id="message-<%= message.id %>">
  <i class="author">
    <% User.find(message.user_id).name ? name = User.find(message.user_id).name : name = "Unknown Cat"  %>
    <span><%= User.find(message.user_id) == current_user ? "me" : name %></span>
    <small><%= message.created_at.strftime("%a %b %e at %l:%M%p") %></small>
  </i>
  <p><%= message.content %></p>
</div>

cable.yml

development:
  adapter: async

test:
  adapter: test

production:
  adapter: redis
  url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
  channel_prefix: Cat_Tinder_production
Onur Karadeniz
  • 69
  • 1
  • 11
  • 1
    Your code seems correct and complete, it should work. I'd say something not directly related to the code you shared is playing a role in this not working for you. – axelduch Mar 02 '22 at 13:09
  • @axelduch thank you! weird thing is I just created a brand new app just to test and it does work there! Im going nuts here. Why else would this happen? – Onur Karadeniz Mar 02 '22 at 13:16
  • 1
    It could come from one/more of these: - the html/js for the message form itself is not behaving properly in every browser, you could check that clicking on the submit button - the database could be in a state that you are not expecting it to be, check models in the database and maybe the scheme/migrations, even though it seems unlikely You can Investigate the network tab, to find this "cable" websocket that will show the subscription activity, compare with the other project that works for you, any difference in the activity will be helpful to find exactly where it fails – axelduch Mar 02 '22 at 13:34
  • Sure no worries, good luck! – axelduch Mar 02 '22 at 13:47
  • In my time spent working with actionCable something I have found to be annoying is the default development setup being set to async. It seems buggy and inconsistent so I use redis as the default with much better results. – Dalemonaco Mar 03 '22 at 19:03

0 Answers0