LiveView upgrade - getting error: LiveHelpers.module_info/1 is undefined

I’m trying to upgrade to Phoenix LiveView 0.18.8 but I’m stuck at a compilation error that seems to be erlang related.

LiveHelpers can’t find module_info. From what I can tell, module_info is defined in erlang. It must be getting imported from something but I’ve lost that import. I had originally tried replacing Phoenix.LiveView and Phoenix.LiveView.Helpers with just Phoenix.Component … but I finally just put all of the imports back in to try to fix this problem. Unfortunately, nothing is working.

What do I need to import so that my LiveHelpers can access module_info?

== Compilation error in file lib/my_app_web/live_helpers.ex ==
** (UndefinedFunctionError) function MyAppWeb.LiveHelpers.module_info/1 is undefined (function not available)
    (elixir 1.13.3) src/elixir_import.erl:98: :elixir_import.calculate/6
    (elixir 1.13.3) src/elixir_import.erl:28: :elixir_import.import/4
    expanding macro: MyAppWeb.__using__/1
    lib/my_app_web/live_helpers.ex:5: MyAppWeb.LiveHelpers (module)
    (elixir 1.13.3) expanding macro: Kernel.use/2
    lib/my_app_web/live_helpers.ex:5: MyAppWeb.LiveHelpers (module)

My imports look like this …

defmodule MyAppWeb.LiveHelpers do
  require Logger
  import Phoenix.LiveView
  import Phoenix.Component
  use MyAppWeb, :live_component
  import Phoenix.LiveView.Helpers
  alias Timex

  use Phoenix.HTML

Hard to say for certain without seeing the MyAppWeb definition, but my suspicion based on that stacktrace is that this is happening:

  • something is importing MyAppWeb.LiveHelpers which starts compiling it
  • MyAppWeb.LiveHelpers calls use MyAppWeb, :live_component
  • the code in MyAppWeb ends up doing… import MyAppWeb.LiveHelpers, which IS NOT DONE COMPILING YET and fails with the message you see

That sounds right because the reason I added MyAppWeb, :live_component is because LiveHelpers could no longer see that function.

If I remove “use SketchLinksWeb, :live_component” then I stop getting the “module_info” error. Unfortunatley, now I get an error saying “undefined function live_component/2”

Should I just alias MyAppWeb and then use live_component that way?

Hmmm. I thought my app was using the live_component function definition from MyAppWeb. But now I’m realizing it was getting it from Phoenix.LiveView.Helpers. In Phoenix.LiveView.Helpers, it is defined as:

  defmacro live_component(component, assigns, do_block \\ []) do

But Phoenix.Component defines it as:

  def live_component(assigns)

live_component is being used in LiveHelpers as follows. I didn’t write this code. This was auto-generated when I first started using LiveView 3 years ago.

def live_modal(component, opts) do
    path = Keyword.fetch!(opts, :return_to)
    modal_opts = [id: :modal, return_to: path, component: component, opts: opts]
    live_component(MyAppWeb.ModalComponent, modal_opts)