0

I'm currently working on a way to add the user avatar to ActionCable chatroom posts. I made some progress with regards to getting the message to insert after changing the coffee script code to support the user.user_profile.avatar.profile_thumb extension method. The issue is, I am receiving 'undefined' in the view when the avatar is not present. I have a conditional statement in the _message.html.erb template already. That is supposed to replace the user avatar with a placeholder image if its not present. How can I change my code to correctly insert either the placeholder img or the avatar when available? I'm using Carrierwave for the images.

_message.html.erb

<div class="media"><% if message.user.user_profile.avatar.profile_thumb.present? %><%= image_tag message.user.user_profile.avatar.profile_thumb, class: "d-flex align-self-start mr-3 img-thumbnail rounded" %><% else %><img class="d-flex align-self-start mr-3 purple-rounded rounded" src="http://via.placeholder.com/30x30"><% end %><div class="media-body"><h5 class="mt-0"><%= message.user.username %></h5> <p><%= message.body %></p></div></div>

chatrooms.coffee

App.chatrooms = App.cable.subscriptions.create "ChatroomsChannel",
  connected: ->
# Called when the subscription is ready for use on the server

  disconnected: ->
# Called when the subscription has been terminated by the server

  received: (data) ->
    active_chatroom = $("[data-behavior='messages'][data-chatroom-id='#{data.chatroom_id}']")
    if active_chatroom.length > 0

      if document.hidden
        if $(".strike").length == 0
          active_chatroom.append("<div class='strike'><span>Unread Messages</span></div>")

        if Notification.permission == "granted"
          new Notification(data.username, {body: data.body})

      else
        App.last_read.update(data.chatroom_id)

      # Insert the message
      active_chatroom.append("<div class='media'><img class='d-flex align-self-start mr-3 purple-rounded rounded' src='http://via.placeholder.com/30x30'>#{data.profile_thumb}<div class='media-body'> <h5 class='mt-0'>#{data.username}</h5> <p>#{data.body}</p></div></div>")

    else
      $("[data-behavior='chatroom-link'][data-chatroom-id='#{data.chatroom_id}']").css("font-weight", "bold")

  send_message: (chatroom_id, message) ->
    @perform "send_message", {chatroom_id: chatroom_id, body: message}
Johnny C
  • 121
  • 1
  • 1
  • 11

1 Answers1

0

When you broadcast to action cable you can send a generated string. With rails you can generate a html layout as a string (all ruby code in the layout will be executed), then send that with your data.

 html = render_to_string(partial: 'messages/messages_drop_in', formats: :html, layout: false, locals: {YOUR NEEDED LOCALS})

After broadcasting. In your coffee:

active_chatroom.append(data.html)

References

http://api.rubyonrails.org/v5.1/classes/AbstractController/Rendering.html http://guides.rubyonrails.org/action_cable_overview.html

Hope this helps out!

Jon
  • 1,954
  • 1
  • 15
  • 13