dvartic
Find pid of another LiveView for use in send_update
I am new to Elixir and Phoenix, so I apologize if the question is stupid.
I am developing an ecommerce site, and I have a cart drawer located in a layout, using LiveComponent.
After adding an item to cart from another component, that as I understand it, lives in another process, I want to send an update to this LiveComponent so that it updates without a page refresh or navigation.
I found send_update which seems to do what I want Phoenix.LiveView — Phoenix LiveView v1.0.0-rc.1
To use this, I need to find PID of this other Liveview. Things I tried:
Process.info(self())Does not return assigned name of the processProcess.register(self(), :cart_liveview)Fails due to a name already existing- Using the
idthat I pass tolive_renderfrom the layout, to render everything. Does not find it.
I am using Process.whereis to get PID from name.
Relevant code:
handle_event snippet on product page
# Save
properties_enc = Jason.encode!(values)
Carts.add_to_cart(cart_id, product_id, properties_enc)
# PID<0.4190.0>
pid = Process.whereis(:cart_liveview)
send_update(CartModal, id: "cart_modal", hello: "from_save")
{:noreply,
socket
|> push_event("js-exec", %{
to: "#confirm-modal",
attr: "data-show-drawer"
})}
Liveview load on layout
<div class="flex items-center gap-4 font-semibold leading-6 text-zinc-900">
<%= live_render(@socket, PhoenixDemoWeb.Layouts.Components.CartLiveView, id: :cart_liveview) %>
</div>
Live Component load
defmodule PhoenixDemoWeb.Layouts.Components.CartLiveView do
use PhoenixDemoWeb, :live_view
alias PhoenixDemoWeb.PutCartCookie
alias PhoenixDemo.Carts
@impl true
def mount(_params, session, socket) do
# Load cart
cart_id = session[PutCartCookie.cart_id_cookie_name()]
cart = Carts.get_cart_with_products(cart_id)
socket = assign(socket, cart: cart)
{:ok, socket}
end
@impl true
def render(assigns) do
~H"""
<.live_component
module={PhoenixDemoWeb.Layouts.Components.CartModal}
id="cart_modal"
cart={@cart}
/>
"""
end
end
Any ideas? Does what I’m doing even make sense?
Marked As Solved
JohnnyCurran
You should be using Phoenix.PubSub to communicate between processes – Phoenix.PubSub — Phoenix.PubSub v2.2.0
The LiveView you want should subscribe to a topic and then any other process can broadcast messages to said topic
Don’t try to find the pid of a process, that’ll only cause pain.
Also Liked
dvartic
So I implemented a PubSub system using Phoenix.Channels. Works really well. I don’t have users implemented right now, but if I did, it would even sync the cart between the same user on different computers, which is extremely cool.
I have doubts about wether to use PubSub directly or Channels, Channels added a bit of a layer, essentially it’s the same thing as far as I can tell, so I used that.
Leaving some snippets here in case it’s helpful to someone. In terms of code it is extremely simple:
- Subscribe to the channel in the Cart element, which will be receiving messages. A channel can be specific to a user, multiple users or all users, in my case, every user has it’s own channel determined by the cart_id. If all shared the same channel, you can use
@topic "channel_name"and then reference it as your channel name in the component.
Handle each message in handle_info, I chose to pass the complete cart but you can do anything.
@impl true
def mount(_params, session, socket) do
cart_id = session[PutCartCookie.cart_id_cookie_name()]
# Subscribe to cart channel
PhoenixDemoWeb.Endpoint.subscribe("cart:" <> Integer.to_string(cart_id))
# Load cart
cart = Carts.get_cart_with_products(cart_id)
socket = assign(socket, cart: cart)
{:ok, socket}
end
@impl true
def handle_info(msg, socket) do
{:noreply, assign(socket, cart: msg.payload.cart)}
end
- Send data from somewhere else, in my case, when adding product to the cart in the product page:
new_cart = Carts.add_to_cart(cart_id, product_id, properties_enc)
PhoenixDemoWeb.Endpoint.broadcast_from(
self(),
"cart:" <> Integer.to_string(cart_id),
"add_to_cart",
%{
cart: new_cart
}
)
And that is it.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









