I am learning Phoenix PubSub by writing a tutorial. I kind-of-sort-of know it. I can kludge it together well enough to make an app - but I don’t understand it with confidence.
The code to develop my tutorial begins with a simple app where a user has two live views and these are set on two different routes.
/send and /receive
/send has a form and when submitted /receive renders the result in real time.
It’s that simple, that’s all it does with no extra code. Minimalist and understandable.
The code works, I understand it and it’s posted below.
A while ago I bought the Pragmatic Studio" video tutorial on Phoenix LiveView. The section on PubSub was too complicated for me to follow so I gave up on it. I revisited it tonight and here is my question.
In my code (below) I use AppWeb.Endpoint to access the broadcast and subscribe methods. This works fine.
In the Pragmatic Studio example they use Phoenix.PubSub
I tried changing my code to mimic their style and my app broke.
I am curious what style should be used, why it should be used and how to update my code to use their style. I’ve posted an image explaining what they do via an imgur link here:
Thank you.
My Code
Router
scope "/", AppWeb do
pipe_through :browser
live "/send", SendLive, :home
live "/receive", ReceiveLive, :home
get "/", PageController, :home
end
This is the code for /send
defmodule AppWeb.SendLive do
use AppWeb, :live_view
def mount(_params, _session, socket) do
{:ok, socket}
end
def handle_event("send", %{"text" => text}, socket) do
IO.inspect text
AppWeb.Endpoint.broadcast(topic, "message", text) # Broadcast
{:noreply, socket}
end
defp topic do #Topic
"chat"
end
def render(assigns)do
~H"""
<div>
<h1>Send Message</h1>
<form phx-submit="send">
<input type="text" name="text" />
<button type="submit">Send</button>
</form>
</div>
"""
end
end
This is the code for /receive
defmodule AppWeb.ReceiveLive do
use AppWeb, :live_view
def mount(_params, _session, socket) do
if connected?(socket) do
AppWeb.Endpoint.subscribe(topic) # PubSub Subscribe
end
{:ok, assign(socket, messages: "")}
end
def handle_info(%{event: "message", payload: message}, socket) do # Handle Info is needed
IO.inspect message
{:noreply, assign(socket, messages: message)}
end
defp topic do # Topic
"chat"
end
def render(assigns)do
~H"""
<div>
<h1>ChatLive</h1>
<%= @messages %>
</div>
"""
end
end