diff --git a/lib/phoenix_live_view/channel.ex b/lib/phoenix_live_view/channel.ex index ee919411aa..c58d6bbb87 100644 --- a/lib/phoenix_live_view/channel.ex +++ b/lib/phoenix_live_view/channel.ex @@ -21,6 +21,7 @@ defmodule Phoenix.LiveView.Channel do @prefix :phoenix @not_mounted_at_router :not_mounted_at_router @max_host_size 253 + @events :e def start_link({endpoint, from}) do hibernate_after = endpoint.config(:live_view)[:hibernate_after] || 15000 @@ -799,6 +800,7 @@ defmodule Phoenix.LiveView.Channel do |> Map.put(:to, to) new_state + |> push_pending_events_on_redirect(new_socket) |> push_redirect(opts, ref) |> stop_shutdown_redirect(:redirect, opts) @@ -806,6 +808,7 @@ defmodule Phoenix.LiveView.Channel do opts = copy_flash(new_state, flash, opts) new_state + |> push_pending_events_on_redirect(new_socket) |> push_redirect(opts, ref) |> stop_shutdown_redirect(:redirect, opts) @@ -813,6 +816,7 @@ defmodule Phoenix.LiveView.Channel do opts = copy_flash(new_state, flash, opts) new_state + |> push_pending_events_on_redirect(new_socket) |> push_live_redirect(opts, ref, pending_diff_ack) |> stop_shutdown_redirect(:live_redirect, opts) @@ -837,6 +841,11 @@ defmodule Phoenix.LiveView.Channel do end end + defp push_pending_events_on_redirect(state, socket) do + if events = Utils.get_push_events(socket), do: push(state, "diff", %{@events => events}) + state + end + defp patch_params_and_action!(socket, %{to: to}) do destructure [path, query], :binary.split(to, ["?", "#"], [:global]) to = %{socket.host_uri | path: path, query: query} diff --git a/test/phoenix_live_view/integrations/event_test.exs b/test/phoenix_live_view/integrations/event_test.exs index 1631cbecaf..f19f0e6630 100644 --- a/test/phoenix_live_view/integrations/event_test.exs +++ b/test/phoenix_live_view/integrations/event_test.exs @@ -34,6 +34,29 @@ defmodule Phoenix.LiveView.EventTest do assert render(view) =~ "count: 123" end + test "supports events with redirects", %{conn: conn} do + {:ok, view, _html} = live(conn, "/events") + + GenServer.call( + view.pid, + {:run, + fn socket -> + new_socket = + socket + |> Component.assign(count: 123) + |> LiveView.push_event("my-event", %{one: 1}) + |> LiveView.push_event("my-event", %{one: 2}) + |> LiveView.push_redirect(to: "/events") + + {:reply, :ok, new_socket} + end} + ) + + assert_push_event(view, "my-event", %{one: 1}) + assert_push_event(view, "my-event", %{one: 2}) + assert_redirected(view, "/events") + end + test "sends updates with no assigns diff", %{conn: conn} do {:ok, view, _html} = live(conn, "/events")