Is there a way to directly supply assigns to a Phoenix.Component

Let’s say I have a component:

 def hello(assigns) do
    ~H"""
      Hello <%= @first_name> <%= @last_name>
  """

then I can call it like this:

<hello first_name="Thomas" second_name="Anderson">

But can I call it like this somehow?

<% name = %{first_name: "Thomas", second_name: "Anderson"}
<hello assigns={name}>

Is there a way to directly supply a map of assigns like this? I know I can manipulate assigns inside my component, I’m hoping for a way to avoid that and just supply the right argument to the component.

Partially resolving my own question, I see I can directly call component to work around this:

<%= component(&hello/2, name)>

but I’m still trying to find if I can use the nicer heex format somehow

<hello {first_name: "Thomas", second_name: "Anderson"} />
or
<hello {name} />

For the latter keep these in mind: Assigns and HEEx templates — Phoenix LiveView v0.17.7

2 Likes

You’re a star, thankyou. I had ignored that format for some reason, and just found the ~H code again after you posted that, now I understand more. Thanks.

This isn’t in the documentation for components anywhere that I can see. I’ll confirm that and PR something to the right place.

I can’t see why that warning (as it pertains to variable tracking) would apply to <hello {name}>… Are you saying that this format will prevent variable tracking from working?

Not this format, but assigning a variable in the template will break (granular) change tracking in LV.

Got it, thanks.

We’ll do some more looking into what happens with the granular change tracking, as this is actually being used in a wider heex view something like this:

<hello {names[:owner]}>
<hello {names[:subscriber]}>

So while the component itself will not block granular tracking, it looks like using the component like this will break granular tracking. Though, if my understanding is correct, chaning [:owner, :first_name] will therefore cause the entire first component to re-render, but the second component won’t re-render.

Am I correct? Can you suggest a way that would allow me to change the owner’s first name in the names map, and keep the diff to only being the first name inside the first component?