leonardorame

leonardorame

Broadcast messages from api to LiveView controller

Hi, I created a basic LiveView example to test the “broadcast_from” messaging, and it works great. This is my controller:

defmodule HelloWeb.ThermostatLive do                                                                                                                                                       
  use Phoenix.LiveView                                                                                                                                                                     
                                                                                                                                                                                           
  @topic "deployments"                                                                                                                                                                     
                                                                                                                                                                                           
  def render(assigns) do                                                                                                                                                                   
    ~L"""                                                                                                                                                                                  
    <h1>The light is <%= @light_bulb_status %>.</h1>                                                                                                                                       
    <button phx-click="on">On</button>                                                                                                                                                     
    <button phx-click="off">Off</button>                                                                                                                                                   
    """                                                                                                                                                                                    
  end                                                                                                                                                                                      
                                                                                                                                                                                           
  def mount(_params, _session, socket) do                                                                                                                                                  
    HelloWeb.Endpoint.subscribe(@topic)                                                                                                                                                    
    socket = assign(socket, :light_bulb_status, "off")                                                                                                                                     
    {:ok, socket}                                                                                                                                                                          
  end                                                                                                                                                                                      
                                                                                                                                                                                           
  def handle_event(light_bulb_status, _value, socket) do                                                                                                                                   
    HelloWeb.Endpoint.broadcast_from(self(), @topic, "status_change", light_bulb_status)                                                                                                   
    {:noreply, assign(socket, :light_bulb_status, light_bulb_status)}                                                                                                                      
  end                                                                                                                                                                                      
                                                                                                                                                                                           
  def handle_info(%{topic: @topic, payload: light_bulb_status}, socket) do                                                                                                                 
    IO.puts "HANDLE BROADCAST FOR"                                                                                                                                                         
    IO.puts light_bulb_status                                                                                                                                                              
    {:noreply, assign(socket, :light_bulb_status, light_bulb_status)}                                                                                                                      
  end                                                                                                                                                                                      
end                                                                                                                                                                                            

Now, I would like to change the values of light_bulb_status from an external app. To do that I created an /api endpoint named /api/notify and would like it to send messages to the ThermostatLive controller.

This is my NotifyController:

defmodule HelloWeb.NotifyController do                                                                                                                                                     
  use HelloWeb, :controller                                                                                                                                                                
  use Phoenix.LiveView                                                                                                                                                                     
  @topic "deployments"                                                                                                                                                                     
                                                                                                                                                                                           
  def get(conn, _params) do                                                                                                                                                                
    HelloWeb.Endpoint.broadcast_from(self(), @topic, "status_change", "on")                                                                                                                
    {:noreply, Phoenix.LiveView.assign(socket, :light_bulb_status, "on")}                                                                                                                  
    json(conn, %{result: "get"})                                                                                                                                                           
  end                                                                                                                                                                                      
end   

When I call it from cURL with:

curl -H "Content-Type: application/json" "http://127.0.0.1:4000/api/notify"

I get this:

= Compilation error in file lib/hello_web/controllers/notify_controller.ex ==
** (CompileError) lib/hello_web/controllers/notify_controller.ex:8: undefined function socket/0
    (elixir 1.12.3) src/elixir_locals.erl:114: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
    (stdlib 3.16.1) erl_eval.erl:685: :erl_eval.do_apply/6
    (elixir 1.12.3) lib/kernel/parallel_compiler.ex:319: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

How can I broadcast messages from my api to the other controller?

First Post!

egze

egze

It seems you have 2 questions here:

  1. How to broadcast from a phoenix controller?
    You did that with:
HelloWeb.Endpoint.broadcast_from(self(), @topic, "status_change", "on")
  1. How to change a socket assign from a Phoenix controller?
    You can’t directly do it. The line:
{:noreply, Phoenix.LiveView.assign(socket, :light_bulb_status, "on")}

won’t work. There is no socket in a standard Phoenix controller, that’s why you are getting a compilation error. What you should do instead is broadcast a message, receive it in the LiveView in handle_info and there you update the assigns.

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New

Other popular topics Top

malloryerik
Hi, this is for people who, like me, have had some friction using .html.heex templates in VSCode. The solution seems to be, in a hyphena...
New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31307 143
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
klo
Got a question about when to concat vs. prepending items to list then reversing to achieve appending. So i know lists boil down to [1 | ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement