Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Normalize params. #6

Merged
merged 3 commits into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/setup-elixir/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ runs:
steps:
- uses: actions/checkout@v2
- name: Set up Elixir
uses: erlef/setup-beam@988e02bfe678367a02564f65ca2e37726dc0268f
uses: erlef/setup-beam@v1
with:
elixir-version: "${{ inputs.elixir-version }}"
otp-version: "${{ inputs.otp-version }}"
Expand Down
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,14 @@ The first element of the tuple is the live component module and the second is th
Optionally, the tuple can contain an extra first element that needs to be a PID. Though
this might not be useful in the application code (there are way better ways to send events
between processes), it is quite useful when testing. When testing a `LiveView`
it creates a new process for it. Its PID can be accessed through `view.pid`.
it creates a new process for it. Its PID can be accessed through `view.pid`.

## Why are messages without params still receiving empty params?

To normalize how to handle messages. If we could have `handle_info("message_name", _socket)`
or `handle_info({"message_name", _params}, socket)`, you would need to think about whether
the message contains params or not and then use a tuple. With this normalization, you only
care about the message name and whether you need the params or not. Also, after using similar
approaches in the past, sometimes you want to send params and sometimes you don't need to.
In cases like these, it is helpful not having a different behaviour notifying an event without
params and sending an event with _empty_ params.
15 changes: 12 additions & 3 deletions lib/live_view_events/notify.ex
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,20 @@ defmodule LiveViewEvents.Notify do
- A PID.
- A tuple of the form `{Module, "id"}` to send a message to a [`LiveView.Component`](`Phoenix.LiveView.Component`) in the same process.
- A tuple of the form `{pid, Module, "id"}` to send a message to a [`LiveView.Component`](`Phoenix.LiveView.Component`) in a different process.

The event send will take the form of `{message, %{}}`.
"""
def notify_to(nil, _message), do: nil
def notify_to(:self, message), do: notify_to(self(), message)
def notify_to(pid, message) when is_pid(pid), do: send(pid, message)
def notify_to(:self, message), do: notify_to(self(), normalize_message(message))
def notify_to(pid, message) when is_pid(pid), do: send(pid, normalize_message(message))

def notify_to(target, message) when is_tuple(target) do
{pid, module, id} = process_tuple(target)
Phoenix.LiveView.send_update(pid, module, %{:id => id, @assign_name_for_event => message})

Phoenix.LiveView.send_update(pid, module, %{
:id => id,
@assign_name_for_event => normalize_message(message)
})
end

@doc """
Expand All @@ -182,6 +188,9 @@ defmodule LiveViewEvents.Notify do
})
end

defp normalize_message({_message_name, %{} = _params} = message), do: message
defp normalize_message(message_name), do: {message_name, %{}}

defp process_tuple({module, id}), do: {self(), module, id}
defp process_tuple({pid, _module, _id} = target) when is_pid(pid), do: target
end
7 changes: 7 additions & 0 deletions test/live_view_events/notify_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,11 @@ defmodule LiveViewEvents.NotifyTest do
test "notify_to/3 with `nil` target does not break" do
Notify.notify_to(nil, "event", %{some: :params})
end

test "notify_to/2 add default empty params" do
Notify.notify_to(:self, "event")

assert_receive {"event", %{} = params}
assert Enum.empty?(params)
end
end
Loading