When I use embeds_many in liveview the new route doesn't show the input_for

Today I noticed that when using

    embedded_schema do
     ...
      embeds_one :variables, Variables

     end
    
    def changeset(%Variables{} = variables, attrs) do
      variables
      |> cast(attrs, [:id, :name])
    end

My input_for is visible in my /new route
The way I need to.
But when I use

    embedded_schema do
     ...
      embeds_many :variables, Variables, on_replace: :delete

     end
    
    def changeset(%Variables{} = variables, attrs) do
      variables
      |> cast(attrs, [:id, :name])
      |> cast_embed(:variables, with: &Variables.changeset/2, required: true)
    end

The form of input_for some.
Why does this happen?

Needed it to work like embeds_many

My form html is like this:

  <%= f = form_for @changeset, "#" , id: example-form" , phx_target: @myself, phx_submit: "save" %>
   ....
    <%= inputs_for f, :variables, fn i -> %>
                <label>Name form 2</label>
                <%= text_input i, :name_form_2, class: "form-control" %>
                <%= error_tag i, :name_form_2 %>
    <% end %>
  </form>

I added the button in my form.html

<a href="#" phx-click="add-feature">Add feature</a>

my index.html looks like this

 def handle_event("add-feature", _, socket) do
    existing_variants = Map.get(socket.assigns.changeset.changes, :variables, socket.assigns.matrix_priority.variables)

    variables =
      existing_variants
      |> Enum.concat([
        Structure.change_variables(%Variables{temp_id: get_temp_id()}) # NOTE temp_id
      ])
       
    changeset =
      socket.assigns.changeset
        |> Ecto.Changeset.put_embed(:variables, variables)

    IO.inspect(changeset)

    {:noreply, assign(socket, changeset: changeset)}
  end

when i click the button,
nothing happens.
Neither error has shown.

I see that when clicking the button, it returns this with inspect

#Ecto.Changeset<
  action: nil,
  changes: %{
    variables: [
      #Ecto.Changeset<action: :insert, changes: %{}, errors: [],
       data: #Structure.Variables<>, valid?: true>
    ]
  },
  errors: [variables: {"can't be blank", [validation: :required]}],
  data: #Myproject.Structure.<>,
  valid?: false
>

I tried to follow this article, but without success.

I recently build an example using LV with nested inputs: Inputs_for/4 collection indices - #4 by LostKobrakai

2 Likes

That way you put it, I can also run normally with phx-click.

But it came down to the same issue.
When clicking the button, the web page does not update.
I modified the code to look like this:

  def handle_event("add-feature", _, socket) do
    socket =
      update(socket, :changeset, fn changeset ->
        existing = Ecto.Changeset.get_field(changeset, :variables, [])
        Ecto.Changeset.put_embed(changeset, :variables, existing ++ [%{}])
      end)
    IO.inspect(socket)
    {:noreply, socket}
  end

I managed to find the problem.

In case anyone goes through the same thing as me.

Just add the phx_target: @myself in your form