tmk
Hey, just getting started with Phoenix + LiveView, coming from Django and React. I’m a bit overwhelmed by the various ways of approaching templating, so apologies in advance if there’s an obvious solution here.
What I’m looking for is the ability to hook into a LiveView render() call, such that I can calculate derived assigns to pass to the template (i.e. so that I can modify assigns). I’d like to do this to keep my LiveView state small and shaped like an entity store, and derive template usage in the render method, as in React.
I understand that function components support this, when leveraging the ~H sigil, but I’m looking to keep my template separate from the LiveView. As an example, the auto generated core components:
def flash(assigns) do
assigns = assign_new(assigns, :id, fn -> "flash-#{assigns.kind}" end)
~H"""
... template here
What I’m looking to do:
@impl true
def render(assigns) do
assigns = derive_view_model(assigns)
actual_render("template.html.heex", assigns)
end
As I understand, LiveView automatically generates a render() function for the template of the same module name. What I’d like to do is understand how to reproduce that method so that I can customize it, or otherwise hook into it.
My current approach is to hook into assign() calls manually - e.g. socket |> delete_entity(:alerts, alert) |> derive_view_model() . However even in my first LiveView page I have forgotten to do this several times, so I’m hoping there’s a better way.
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #blog-post
- #phoenix_html
- #iex
- #graphql
- #ai
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex











Showing Posts 1 to 8- Show Best Posts
- Show All Posts (oldest first)
- Show All Posts (newest first)
krishandley
I have a function called set_state in pretty much every LiveView which basically does this, yes you have to manually call it where needed. But it’s pretty flexible, you could have different ones depending on how expensive they are, and only call them when needed. But there is no automatic way of doing it.
Zurga
You can use attach_hook/4 to run a function after handle_params, handle_event and handle_info. This will ensure that these derived assigns are set all the time. Use on_mount for hooking into mount
tmk
Reading the docs, I see that hooks are run before the handle_foo handlers:
This would not work for my use case, since I’d be looking to update the derived assigns after the handle_foo methods have run. Eg this code:
I’d need to be able to run a hook post-handler, with the updated assigns, so that the view model may be calculated correctly.
If I’m missing something, please let me know!
tmk
Thanks for the reply - I’m glad I’m not the only one. It stands out to me that it is possible to accomplish this by only leveraging function components (including for
render()) - for consistency, it’d be great to be able to update assigns for template file rendering, too.krasenyp
What you can do, and that’s similar to Emacs’ advice system, is to use the socket as a container for
assignhooks but you need to redefineassign. Something like the following:Zurga
You could do something similar to what Surface does with quoted_mount. Just move the
supercall to run before you do the state handling:sorry for the formatting, I am on mobile now
rhcarvalho
In LiveView “assigns” are state stored in the server.
The bare building blocks you have are a module and functions (thankfully only two concepts).
The LiveView “as a whole” (~page) is a module, all logic goes into functions.
The framework will call callbacks that you implement on your module:
mount,handle_*, etc.The way I approach derived assigns is computing them as a function of their dependencies (often a private function
defpinside the module and called as appropriate).You can as well inline your templates in your LiveView module,
def render(assigns), and then you can do as you wanted/saw in function components as in the CoreComponents module.Note you need to be careful to follow the rules with regards to change tracking: common pitfalls.
tmk
Thanks for all the suggestions. Coming from a React background, I feel most comfortable with @rhcarvalho ‘s approach to inline templates. In React, I’d map
liveview assignstocomponent state, with therender()method in each supporting derived state.