diff --git a/lib/phoenix_live_view/channel.ex b/lib/phoenix_live_view/channel.ex index ee919411aa..ca78e71d7a 100644 --- a/lib/phoenix_live_view/channel.ex +++ b/lib/phoenix_live_view/channel.ex @@ -799,6 +799,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 +807,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 +815,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 +840,12 @@ defmodule Phoenix.LiveView.Channel do end end + defp push_pending_events_on_redirect(state, socket) do + {:diff, diff, _new_state} = render_diff(state, socket, false) + if events = Map.get(diff, :e), do: push(state, "diff", %{:e => 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")