"no function clause matching in handle_event/3" for live field validation

Hello elixir lovers! I encountered a new headache problem. I have a form validation in the live template for changing email and for password. The first one goes well - validation forms (new email and current password), but the second one throws and an error while validating a new password:
no function clause matching in handle_event/3
As you already may guess I have this clause:

  def handle_event("validate_password", %{"password" => password, "current_password" => current_password}, socket) do
    cset = socket.assigns.user
    |> User.password_changeset(password)
    |> User.validate_current_password(current_password)
    |> Map.put(:action, :update)

  IO.puts(inspect(cset))

  {:noreply, assign(socket, password_changeset: cset)}

  end

and here’s my .leex file:

<h1>Settings</h1>

<h3>Change email</h3>

<%= form_for @email_changeset, "#",
  [phx_change: :validate_email, phx_submit: :save_email, phx_hook: "SavedForm"], fn f-> %>
   <%= if @email_changeset.action do %>
    <div class="alert alert-danger">
      <p>Oops, something went wrong! Please check the errors below.</p>
    </div>
  <% end %>


  <%= hidden_input f, :action, name: "action", value: "update_email" %>

  <%= label f, :email %>
  <%= email_input f, :email, required: true, phx_debounce: "blur"%>
  <%= error_tag f, :email %>

  <%= label f, :current_password, for: "current_password_for_email" %>
  <%= password_input f, :current_password, required: true, name: "current_password", id: "current_password_for_email" %>
  <%= error_tag f, :current_password %>


  <div>
    <%= submit "Save", phx_disable_with: "Saving..." %>
  </div>

  <% end %>

  <h3>Change password</h3>

  <%= form_for @password_changeset, "#",
  [phx_change:  :validate_password, phx_submit: :save_password, phx_hook: "SavedForm"], fn f-> %>
   <%= if @password_changeset.action do %>
    <div class="alert alert-danger">
      <p>Oops, something went wrong! Please check the errors below.</p>
    </div>
  <% end %>

  <%= hidden_input f, :action, name: "action", value: "update_password" %>

  <%= label f, :password, "New password" %>
  <%= password_input f, :password, required: true %>
  <%= error_tag f, :password %>

  <%= label f, :current_password, for: "current_password_for_password" %>
  <%= password_input f, :current_password, required: true, name: "current_password", id: "current_password_for_password" %>
  <%= error_tag f, :current_password %>

  <div>
    <%= submit "Save", phx_disable_with: "Saving..." %>
  </div>

  <% end %>

My first thought was that I need to use different templates for changing email and password. Then I thought that maybe handle_event("validate_password …) must take different arguments. Maybe I`m doing it the wrong way and I really need to use different templates for such things. I also heard about live components but I don’t think it will solve this problem.

Please, let me know if some necessary code is missing in my code samples.
Thank you in advance :smiley:

The error sometimes includes the call that was attempted and that should give you a hint as to what is wrong.

Alternatively you can implement a clause like this:

def handle_event(event, params, socket) do
  IO.inspect({event, params}, label: "Got unknown event")
  {:noreply, socket}
end

This way you can follow the log and see what events arrived with what params and easily see how your pattern match was wrong.

2 Likes

Thank you! This is a really handy approach! :smiley: