Reputation: 1605
Whenever a user joins a channel, I want to send them a record of all the previous messages that were sent.
My implementation for handle_info
below triggers this error protocol Jason.Encoder not implemented for Hello.Messaging.Message
.
My guess is that messages
is a list of structs, when it needs to be converted to a list of maps?
use Phoenix.Channel
alias Hello.Messaging
def join("room:" <> room_id, params, socket) do
send(self(), {:after_join, params})
{:ok, assign(socket, :room_id, room_id)}
end
# push triggers the error message here
def handle_info({:after_join, _params}, socket) do
messages = Messaging.list_messages()
push(socket, "messages", %{messages: messages})
{:noreply, socket}
end
def handle_in("new_msg", %{"body" => body}, socket) do
case Messaging.create_message(%{body: body, room_id: socket.assigns.room_id}) do
{:ok, msg} ->
broadcast!(socket, "new_msg", %{body: msg.body})
{:noreply, socket}
{:error, reason} ->
{:error, reason}
end
end
Upvotes: 1
Views: 199
Reputation: 1605
I'm writing my own answer here.
The problem is that messages
from Message.list_messages()
is a list of structs, when push
takes either a map
or tagged {:binary, data} tuple
.
Converting messages
into a map
was the solution:
map_messages = Enum.map(struct_messages, fn s_msg -> Map.take(s_msg, [:id, :body]) end)
Upvotes: 0
Reputation: 121000
Jason.Encoder
is not implemented for structs, and your Hello.Messaging.Message
is a struct.
If you own the struct, enable encoding for it as described in the documentation
@derive {Jason.Encoder, only: [....]}
defstruct # ...
If you cannot modify the struct, convert it to map with Map.from_struct/1
.
Upvotes: 1