All threads / Not Rendering with Stimulus & ActionCable

Ask A Question

Notifications

You’re not receiving notifications from this thread.

Not Rendering with Stimulus & ActionCable

Jim Miller asked in Javascript

Hi,
I'm having some issues with Stimulus and I was hoping that someone could review this code and see if they see anything that I missed.
The Rails part is working and saving to the db. I'm sure that I have a typo somewhere...

Here is what I have:

app/channels/message_channel.rb

class MessageChannel < ApplicationCable::Channel
  def subscribed
    stream_from 'message_channel'
  end

  def unsubscribed
    stop_all_streams
  end
end

app/javascript/controllers/message_list_controller.js

import { Controller } from "stimulus";
import consumer from "../channels/consumer";

export default class extends Controller {
  static targets = ["input", "messages"];
  connect() {
    this.channel = consumer.subscriptions.create("MessageChannel", {
      connected: this._cableConnected.bind(this),
      disconnected: this._cableDisconnected.bind(this),
      received: this._cableReceived.bind(this),
    });
  }

  clearInput() {
    this.inputTarget.value = "";
  }

  _cableConnected() {}

  _cableDisconnected() {}

  _cableReceived() {
    this.messagesTarget.innerHTML += data.message;
  }
}

app/controllers/messages_controller.rb

class MessagesController < ApplicationController
  before_action :set_message, only: [:show, :edit, :update, :destroy]

  def index
    @messages = Message.all
  end

  def create
    @message = Message.new(params.require(:message).permit(:content))
    @message.save!
    ActionCable.server.broadcast('message_channel', message: (render @message))
    head :ok
  end


  private
  def set_message
    @message = Message.find(params[:id])
  end

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

app/views/messages/index.html.erb

<p id="notice"><%= notice %></p>

<h1>Messages</h1>

<div data-controller='message-list'>
  <div data-target='message-list.messages'>
    <%= render @messages %>
  </div>

  <%= form_with(model: Message.new, 
                data: { action: 'ajax:success->message-list#clearInput' }) do |form| %>
                <%= form.text_area :content, 
                  data: { target: 'message-list.input' }, rows: 1, autofocus: true %>
                <%= form.submit class: "btn btn-default" %>
              <% end %>
</div>

Gist of Logfile

Thanks!

In case someone stumbles across this and needs an answer. Modify message_list_controller:

app/javascript/controllers/message_list_controller.js

_cableReceived(data) {
    this.messagesTarget.innerHTML += data.message;
  }
Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 48,387+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Ruby on Rails tutorials, guides, and screencasts for web developers learning Ruby, Rails, Javascript, Turbolinks, Stimulus.js, Vue.js, and more. Icons by Icons8

    © 2021 GoRails, LLC. All rights reserved.