How to access the current_user inside of my live_component?

@adw632 said that, not me. Though incidentally, I’m also an Andrew H :sweat_smile:

1 Like

oh I am so sorry to both of you, Andrew H’s.

1 Like

Your default_assigns function computes a derived value:

defmodule UI.Live.Helpers do
  def default_assigns(assigns) do
    {current_user: assigns.current_user, current_company: assigns.current_company, current_store: ... }
  end
end

The derived value is then used with one of the pitfalls in the article I referenced that LiveView cannot optimise:

<.hello_component {%{greeting: @greeting, person: @person}} />

In your case LiveView must call your render function always because it has to evaluate default_assigns every time. LiveView is unable to “detect” the discrete inputs because @user and @company assigns are not provided to the template. What LiveView sees is some arbitrary code providing a value which must be evaluated every time:

<.my_component {default_assigns(assigns)} />

as opposed to the following, which provides more information to LiveView so it knows it never even has to call your render function and never has to evaluate a default_assigns each time because the data dependencies user and company in the socket assigns never changed.

<.my_component user={@user} company={@company} />

or similarly using a single scope assigns:

<.my_component scope={@scope}  />

Any time you “hide” the data dependency from LiveView there is more work on the server to unconditionally re-render the template, recompute a derived value and more state transferred on the wire to the client and more work on the client to update the DOM.

As you have found assigning a “scope” to socket assigns allows liveview to see the data dependency and optimise rendering, state transfer and DOM updates.

Be aware that if scope contains fields that are changing, LiveView will have to re-render, so it’s best to keep fields that are changing as separate discrete attributes that you pass to your templates explicitly to limit rerendering to only the places where that field is used.

3 Likes

that makes sense thank you!

Just for posterity, when I say the new way of handling “default_params” I meant that’s one of many things %Scope{} is good for. I should have really written %MyApp.Scope{} as it’s a context you can pass around in both your business and web layers.

3 Likes

Nice find @sodapopcan

I thought it might be useful to note the modules in todo trek that work together with the scope concept:

4 Likes