Assign and assign_new missing in liveview 0.18.0 - what are we meant to use instead?

I’m getting a compilation error because apparently assign and assign_new now only exist in the Phoenix.Component namespace. My hook file has an import Phoenix.LiveView line in it. What are we meant to use instead? Can’t find a mention of its removal in the liveview docs.

** (CompileError) lib/app_web/hooks/auth.ex:21: undefined function assign/3 (expected AppWeb.Hooks.Auth to define such a function or for it to be imported, but none are available)

They has been moved to Phoenix.Component module as same as live_flash/2.

Be sure to check out the changelog which talks about these changes:

2 Likes

Thanks, was looking for that. Fwiw, it seems a little odd to import what’s essentially a bunch of html helpers into a middleware module. Do you have a link to any discussion regarding this change? Curious to read what the thought process is.

2 Likes

I’m in this camp also. I’m finding that I have many cases where a module uses “socket” functions that are now split between Phoenix.Component and Phoenix.Liveview. example: assign/2 and push_patch/2. So I guess it will be common boilerplate to see

import Phoenix.Component
import Phoenix.LiveView

Am I missing a magic

use Phoenix something

that would pull in all “socket” functions?

It’s probably not the preferred methodology, but when I was hacking things together for my LiveView socket assigns I found that importing Phoenix.LiveView.Utils did the trick for me.

defmodule Demo17devWeb.InitAssigns do
  import Phoenix.LiveView
  import Phoenix.LiveView.Utils
...
end

Hi @ltd

check the file lib/_web.ex. At the bottom, there is the view_helpers/0 function that does the imports in all live view and view module that make use of

use <YourApp>_web, :live_view
use <YourApp>_web, :view

Utils is private :slight_smile:

My rule of thumb is to always use the :only option with import unless the module was specifically designed to be imported. In this case, Phoenix.LiveView is designed to be use’d, not import’d, so I always either specify the functions I want or, if there are only a couple of calls, just spell out the whole module path and ditch the import altogether. If you find yourself doing import Foo, only: [bar: 1] over and over and over again in a particular type of module, that’s a good opportunity to extract a named concept, like a Middleware module, that you can use to do that specific import for you. In this case, it would import the two Phoenix modules and I would still advise using :only with them. To drive the point a little further: it doesn’t make sense to import any of the handle_ or rendering functions into middleware either.