I am trying to add a component that relies on components in core_components and it's beating me

So, I tried doing it in a separate file, and then I tried doing it IN the core components file itself, and I get this error:

<.simple_form :let={f} for={@changeset} action={~p"/action"}>

The open bracket seems to trigger an error:

undefined function sigil_p/2 (expected MyApplication.MyComponent to define such a function or for it to be imported, but none are available)

If try to add it into the core_components file directly, I get the same error, except that it wants CoreComponents to define it.

I see other <. notations in core_components working without problem, so I expect I am missing something else, but the error message has left me baffled, and googling is not giving me answers.

Any thoughts?

This error is telling you it can’t find sigil_p which is what implements ~p"....". That sigil is defined in Phoenix.VerifiedRoutes so you need to import Phoenix.VerifiedRoutes somewhere in your module.

1 Like

Thank you. That got me to the next level of expecting @endpoint to be set. I moved this code from a controller which instantiated a hierarchy of templates, passing things down through the templates into the concept of a component, which would be self contained, and not need everything passed down through the hierarchy.

But I was obviously benefitting from the Controller parentage in ways that Component is differently set up. I think I see how Controller obtains this data, so hopefully I can adapt it into Controller…

Answering myself, the :controller atom builds out all the dependencies including a fully configured VerifiedRoutes, but moving the code to an independent component lost that. The full answer was to add:

  use Phoenix.VerifiedRoutes,
    endpoint: MyApplicationWeb.Endpoint,
    router: MyApplicationWeb.Router,
    statics: MyApplicationWeb.static_paths()

And yes, we could build that into a :component atom also, although I haven’t done that yet.