coen.bakker

coen.bakker

This must be something minor, but I can’t seem to put my finger on it. Why are the values of the <.form> not reset on a successful phx-submit?

defmodule AppWeb.SomePageLive
  def render(assigns) do
    ~H"""
      <.live_component
        id="some-id"
        module={AppWeb.PostingBarComponent}
        topic={@selected_topic}
        user={@current_user}
      />
    """
  end
end
defmodule AppWeb.PostingBarComponent
  use Phoenix.LiveComponent
  use AppWeb, :html
  import Phoenix.HTML.Form

  def mount(socket) do
    {:ok, assign(socket,
      post_draft: to_form(empty_changeset())
    )}
  end

  def render(assigns) do
    ~H"""
    <div>
      <.form
        for={@post_draft}
        id="form-id"
        phx-submit="submit_post"
        phx-target={@myself}
      >
        <%= textarea(@post_draft, :content,
          id: "post-input",
          rows: 1,
          placeholder: "Post to ##{@topic.name}"
        ) %>
        <button type="submit">Submit</button>
      </.form>
    </div>
    """
  end

  def handle_event("submit_post", %{"post" => post}, %{assigns: assigns} = socket) do
    %{topic: topic, user: user} = assigns
    %{"content" => content} = post

    case App.Social.create_post(content, topic.id, user.id) do
      {:ok, _} ->
        {:noreply, assign(socket,
          post_draft: to_form(empty_changeset())
        )}

      {:error, changeset} ->
        {:noreply, assign(socket, post_draft: to_form(changeset))}
    end
  end

  defp empty_changeset() do
    %App.Social.Post{}
    |> Ecto.Changeset.change()
  end
end

Showing Posts 1 to 10

coen.bakker

coen.bakker OP

Is seems like {:noreply, assign(socket, post_draft: to_form(empty_changeset()))}, after a successful submit, is not triggering the expected component rerender.

coen.bakker

coen.bakker OP

Away from computer, so can’t check, but I guess it could be the fact that the value of th assign post_draft on mount and after submit are the same. Both are an empty changeset.

I could update the form assign on phx-change in addition to phx-submit, but that seems suboptimal, since I am only interested in the value of the form input directly after the submit event.

Or are you supposed to use phx-change? Be it, with or without debouncing?

ahallock

ahallock

I ran into this problem the other day. The only good solution I found was to use phx-change as you suggested. Another thing that worked was assigning a random ID – to_form(id: my_random_id) – to the form but that feels like a hack.

sodapopcan

sodapopcan

Ha, I’ve been silently coming back to this thread and couldn’t for the life of me figure out what the problem was (I didn’t actually try and reproducing it locally, of course).

I always add ids to forms for testing purposes so that explains why I’ve never run into it. For that reason I don’t find it particularly hacky—Since LiveView is all about ids, I’ve switched away from patterns like data-test-id to a having a convention around plain ol’ html ids which reduces a lot of noise.

coen.bakker

coen.bakker OP

I’ve been in thinking about that recently: using ids instead of data attributes for testing. Not committed to it yet, but indeed LiveView does rely a lot on ids already.

coen.bakker

coen.bakker OP

I opted for adding a private function that randomizes the ids, thanks.

  defp to_unique_form(changeset) do
    to_form(changeset, id: "form-#{System.unique_integer()}")
  end

  defp empty_changeset() do
    %App.Social.Post{}
    |> Ecto.Changeset.change()
  end
sodapopcan

sodapopcan

You definitely do not want to do this as it could have unintended consequences on change tracking. I had this idea before and was swiftly reminded that this was the case!

coen.bakker

coen.bakker OP

Oh boy. Back to the keyboard :sweat_smile:.

sodapopcan

sodapopcan

Since you have a live component for which you must provide an id already, you can get a unique form id with: id=“#{@component_id}-form}”! I’m sure some people would scoff at the redundant “form” token in their id, but I personally don’t care about that stuff and this is exactly what I do.

coen.bakker

coen.bakker OP

I thought the idea of using the form id was to nudge LiveView into rerendering the form when the form data alone does not trigger a rerender, by using a different form id on each submit. Interestingly enough all my tests pass, when I use random ids. :stuck_out_tongue:

If I just set an id with to_form(id: "some_id"), my form is not reset.

Also, I actually have little insight into how large the costs are of using phx-change="some_event" on a form, in addition to phx-submit. I catch myself assuming that the costs are relevant/not negligible.

Where Next? Top

Trending in Discussions Top

AstonJ
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
2977 94592 917
New
cblavier
Hey there, It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
heathen
Quite interesting article Google brought me. Didn’t find any mentions about it here. What do you think in general? Would you use togethe...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
AstonJ
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New
maennchen
:warning: Security advisory: Decimal DoS vulnerability A vulnerability has been published for decimal where very large exponents can cau...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews