Skip to content

Commit 6978284

Browse files
authored
Accept function in Phoenix.Socket.assign/2 (#6530)
* Add Phoenix.Socket.assign_lazy/3 * Refactoring
1 parent 4252878 commit 6978284

File tree

2 files changed

+19
-1
lines changed

2 files changed

+19
-1
lines changed

lib/phoenix/socket.ex

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,20 +345,29 @@ defmodule Phoenix.Socket do
345345

346346
@doc """
347347
Adds key/value pairs to socket assigns.
348+
Accepts a keyword list, a map, or a single-argument function.
348349
349-
A keyword list or a map of assigns must be given as argument to be merged into existing assigns.
350+
When a keyword list or map is provided, it will be merged into the existing assigns.
351+
352+
If a function is given, it takes the current assigns as an argument and its return
353+
value will be merged into the current assigns.
350354
351355
## Examples
352356
353357
iex> assign(socket, name: "Elixir", logo: "💧")
354358
iex> assign(socket, %{name: "Elixir"})
359+
iex> assign(socket, fn %{name: name, logo: logo} -> %{title: Enum.join([name, logo], " | ")} end)
355360
356361
"""
357362
def assign(%Socket{} = socket, keyword_or_map)
358363
when is_map(keyword_or_map) or is_list(keyword_or_map) do
359364
%{socket | assigns: Map.merge(socket.assigns, Map.new(keyword_or_map))}
360365
end
361366

367+
def assign(%Socket{} = socket, fun) when is_function(fun, 1) do
368+
assign(socket, fun.(socket.assigns))
369+
end
370+
362371
@doc """
363372
Defines a channel matching the given topic and transports.
364373

test/phoenix/socket/socket_test.exs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,15 @@ defmodule Phoenix.SocketTest do
8080
assert socket.assigns[:foo] == :baz
8181
assert socket.assigns[:abc] == :def
8282
end
83+
84+
test "accepts functions" do
85+
socket = %Phoenix.Socket{}
86+
assert socket.assigns[:foo] == nil
87+
socket = assign(socket, :foo, :bar)
88+
assert socket.assigns[:foo] == :bar
89+
socket = assign(socket, fn %{foo: :bar} -> [baz: :quux] end)
90+
assert socket.assigns[:baz] == :quux
91+
end
8392
end
8493

8594
describe "drainer_spec/1" do

0 commit comments

Comments
 (0)