Actually I forgot about components … Ideally there should be 4 ways to get PIDs of 3 types.
A server PID would be a JS equivalent for Elixir process that works like a proxy with server process. The message would be send via WebSocket.
A client PID would be a JS equivalent for Elixir process that works like a proxy with client process. The message would be send to current page (client side).
A component PID would be a JS equivalent for Elixir’s self() process. We simply want to send message to current component (anonymous function, action or command).
The fourth way would be an easy way to get a parent component PID or page PID. This is for “just send to parent whoever it is”. This would be nice feature for a behaviour-like implementations of some actions and commands.
defmodule MyApp.GreetingPage do
use Hologram.Page
route "/hello/:username"
layout MyApp.MainLayout
def init(params, component, server) do
component
|> put_state(:client_pid, component.client_pid)
|> put_state(:component_pid, component.pid)
|> put_state(:server_pid, server.pid)
end
def template do
~HOLO"""
<div>To communicate with app use following process identifiers:</div>
<ul>
<li>Client PID: {@client_pid}!</li>
<li>Component PID: {@component_pid}!</li>
<li>Server PID: {@server_pid}!</li>
</ul>
"""
end
end
With that we can use those PID to send a message:
# optional 3rd argument for passing data
holo_send(client_pid, :action_name)
holo_send(server_pid, :command_name)
holo_send(component_pid, {:action, :action_name})
holo_send(component_pid, {:command, :command_name})
# raises no such action error:
holo_send(client_pid, :command_name)
# raises no such command error:
holo_send(server_pid, :action_name)
# same for holo_send_after
Yes, client_pid and component_pid may send same actions as well as server_pid and component_pid may send same commands. This would happen only if component is a page. However all of those PIDs needs to represent different process (or JS equivalent) so that we can send strict actions to client or commands to server and alternatively send generic actions and commands within current component regardless if current component is page or not.
This way client_pid and server_pid would be recommended to use directly within init, command or action and component_pid would be used in more generic cases like external hex packages. Look that some developers may want to use actions as equivalent of JS intervals - i.e. background process that send message to itself (same action name) after specified time and based on some condition based on send data (if any).