Return the result of an Elixir function in an onClick handler?

Hello everyone

I am starting to get back into Elixir and found myself with an issue where I have an phx-click that is getting triggered on page mount. I do not recall this being an issue before, but cannot seem to find any resources about it. There was a post here which seemed similar but the conclusion there did not really leave me with anything to take away.

Here is my controller:

defmodule MyAppWeb.ApplicationController do
  use MyAppWeb, :controller
  alias MyApp.Repo
  alias MyApp.Site.Application

  def home(conn, %{"application_slug" => application_slug} = params) do
    app = Repo.get_by(Application, application_slug: application_slug)
    conn
    |> put_flash(:info, "Hello")
    |> assign(:layout, false)
    |> assign(:application, app)
    |> render(:home)

    # render(conn, :home, layout: false, supplier_list: suppliers)
  end

  def register_for_doc_review(application_id) do
    IO.puts("Registering #{application_id} for doc review")
  end
end

and then the page is here:

<.flash_group flash={@flash} />
<div class="px-4 py-10 sm:px-6 sm:py-28 lg:px-8 xl:px-28 xl:py-32">
<.icon name="hero-beaker" class="h-12 w-12 bg-gradient-to-r from-blue-600 via-green-500 to-indigo-400" />
<div class="text-brand mt-10 flex items-center text-sm font-semibold leading-6">
</div>
  <div class="text-center w-2/5 mx-auto border-solid border-2 border-sky-500">
    <p class="text-[2rem] mt-4 font-semibold leading-10 tracking-tighter text-zinc-200">
      <.icon name="hero-beaker" class="mt-2 h-14 w-14 bg-gradient-to-r from-blue-600 via-green-500 to-indigo-400" /> 
      Application
    </p>
    <p>Show the Application</p>
    <p>Name: <%= @application.first_name %></p>
    <p>Name: <%= @application.last_name %></p>
    <button onclick={MyAppWeb.ApplicationController.register_for_doc_review(@application.application_id)}>🔍</button>
  </div>
</div>

Then whenever I go to the page, without clicking or anything in the console I get

Registering 1 for doc review
[info] Sent 200 in 189ms

I guess I am just wondering if this is expected. I would have to suspect I am just implementing something incorrectly as this would have to be something mentioned elsewhere, no?

Also worth mentioning when I do click on it nothing happens.

Thanks all

It’s not the onclick that is triggering, it’s that code inside {} is a function call so it’s being called immediately.

onclick={MyAppWeb.ApplicationController.register_for_doc_review(@application.application_id)}

If you view source, you will see that onclick has the stringified return value of register_for_doc_review(@application.application_id).

Hey @r4z4 as @sodapopcan notes I think there’s a fundamental misunderstanding of a variety of things here:

  1. You talk about live view, but you show a controller. While you can embed live views inside controller rendered pages, you aren’t doing that here. I would recommend building a project that uses live view from the start and has a live page.

  2. You talk about phx-click but your code has onclick

  3. onclick is a browser concept that runs code in your browser (JS), not Elixir functions. Even in LiveView phx-click is used to send a message to your LiveView process, which can then run your server code.

3 Likes

Ok sounds good, thanks. For #2 and #3 I get the same behavior with phx-click, I just changed it to onclick in an attempt to solve the issue.

For #1, this is my attempt to not use liveview. I do not need it here.

I guess I will do some reading. Thanks all.

Right, does @sodapopcan’s explanation there make sense? Stuff inside {} is run when the page is rendered as part of building the HTML, it isn’t like JavaScript string that is triggered to run when clicked.