nidu

nidu

Live view: passing form to nested live component breaks redirection

Hello,

I’m trying to make a live view app with a form that has a nested live component.

page_live.ex -> form_component.ex -> nested_component.ex

(Repro repo is available here https://github.com/nidu/live-view-redirection-issue/tree/main/lib/test_web/live.)

In page_live:

<%= live_component TestWeb.FormComponent,
      id: "test_form",
      return_to: "/" %>

form_component:

defmodule TestWeb.FormComponent do
  use TestWeb, :live_component

  @impl true
  def handle_event("save", _, socket) do
    {:noreply,
     socket
     |> put_flash(:info, "Listing query updated successfully")
     |> push_redirect(to: socket.assigns.return_to)}
  end

  @impl true
  def render(assigns) do
    ~L"""
    <%= f = form_for :model, "#",
      id: "test_form",
      phx_submit: "save",
      phx_target: @myself %>

      <div>Hello</div>
      <div>
        <%= live_component TestWeb.FormComponent.NestedComponent, %{form: f} %>
      </div>
      <button type="submit" phx-target="<%= @myself %>">Save</button>

    </form>
    """
  end
end

In nested_component:

defmodule TestWeb.FormComponent.NestedComponent do
  use TestWeb, :live_component

  @impl true
  def update(%{form: form} = assigns, socket) do
    {:ok,
     socket
     |> assign(assigns)}
  end

  @impl true
  def render(assigns) do
    ~L"""
    """
  end
end

When I press Save in the form - I get an error message like this:

[error] GenServer #PID<0.1118.0> terminating
** (RuntimeError) cannot redirect socket on update/2
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/utils.ex:413: Phoenix.LiveView.Utils.maybe_call_update!/3
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/diff.ex:327: Phoenix.LiveView.Diff.component_to_rendered/4
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/diff.ex:369: Phoenix.LiveView.Diff.traverse/6
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/diff.ex:430: anonymous fn/4 in Phoenix.LiveView.Diff.traverse_dynamic/6
    (elixir 1.11.4) lib/enum.ex:2193: Enum."-reduce/3-lists^foldl/2-0-"/3
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/diff.ex:342: Phoenix.LiveView.Diff.traverse/6
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/diff.ex:584: Phoenix.LiveView.Diff.render_component/9
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/diff.ex:197: Phoenix.LiveView.Diff.write_component/5
    (phoenix_live_view 0.15.7) lib/phoenix_live_view/channel.ex:467: Phoenix.LiveView.Channel.component_handle_event/6
    (stdlib 3.12) gen_server.erl:637: :gen_server.try_dispatch/4
    (stdlib 3.12) gen_server.erl:711: :gen_server.handle_msg/6
    (stdlib 3.12) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
Last message: %Phoenix.Socket.Message{event: "event", join_ref: "4", payload: %{"cid" => 1, "event" => "save", "type" => "form", "value" => "_csrf_token=H2p3EEQ_Pm0LET0qez4EUyMvCH8ePhJCl2Ob1IO7cSrfM_O1ow1FIQq7"}, ref: "5", topic: "lv:phx-FpZOfwN3qcBKnAuH"}
State: %{components: {%{1 => {TestWeb.FormComponent, "test_form", %{flash: %{}, id: "test_form", myself: %Phoenix.LiveComponent.CID{cid: 1}, return_to: "/"}, %{changed: %{}, root_view: TestWeb.PageLive}, {318716392023482915064364044808860968093, %{1 => {110892913394776534321848086767214048172, %{}}}}}}, %{TestWeb.FormComponent => %{"test_form" => 1}}, 2}, join_ref: "4", serializer: Phoenix.Socket.V2.JSONSerializer, socket: #Phoenix.LiveView.Socket<assigns: %{flash: %{}, live_action: :index, query: "", results: %{}}, changed: %{}, endpoint: TestWeb.Endpoint, id: "phx-FpZOfwN3qcBKnAuH", parent_pid: nil, root_pid: #PID<0.1118.0>, router: TestWeb.Router, transport_pid: #PID<0.1115.0>, view: TestWeb.PageLive, ...>, topic: "lv:phx-FpZOfwN3qcBKnAuH", upload_names: %{}, upload_pids: %{}}

The way to get rid of this message:

  • Don’t pass form to nested component (e.g. instead of form: f pass form: 1). I need to pass form, so that’s not an option.
  • Remove update method from nested component. This is a viable option but I’d still like to do something in my update
  • Remove put_flash from save handler. This is an option but it’s still weird

I think it should work but for some reason it doesn’t and it somehow breaks when I pass the form that I need to pass. What’s the issue here?

Where Next?

Popular in Questions Top

SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
AstonJ
You’re a programmer, so you don’t need spoon feeding with the conventional drivel about “this is an integer.” No. You need to know what’s...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New

We're in Beta

About us Mission Statement