ydd
Hi all,
I’m a bit confused about the role of handle_params in the LiveView life cycle. I’ve read Phoenix.LiveView — Phoenix LiveView v1.2.5 many times and I still don’t understand it, hopefully someone can clarify.
Let me lay out what I understand from the docs:
mountis called twice, once on the initial HTTP request and again on the websocket connect. (BTW the docs read “once per LiveView life-cycle” which is quite confusing).handle_paramsis called aftermount, meaning it’s also called twice.- Both
mountandhandle_paramstake the same arguments and trigger a render.
The docs suggest we should load data in mount as it’s called once and mention handle_params is used to handle live_patch operations showing the following example:
def handle_params(params, _uri, socket) do
socket =
case params["sort_by"] do
sort_by when sort_by in ~w(name company) -> assign(socket, sort_by: sort)
_ -> socket
end
{:noreply, load_users(socket)}
end
load_users(socket) is not listed but it implies it’s a function that load the users from somewhere and sorts it using sort_by. Assuming we’re also loading data in mount wouldn’t that mean the loading is happening twice?
If handle_params is called regardless, takes the same arguments as mount, and is invoked on live_patch whereas mount is not, why not always load the content there instead of in mount?
Are we supposed to avoid loading if some elements are already present in the socket.assigns from mount?
It may be that I’m misunderstanding something but I’ve been confused about this for a while.
Thanks in advance!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
stefanchrobot
I’m just starting out with LiveView, but I think to me it would be cleaner to have separate callbacks for connected and disconnected mount, something like
static(init?) naconnectedinstead of justmount. As you wrote,handle_paramsadds even more to the mix, but that’s related to navigation, which I haven’t used so far.josevalim
You would load it on
mountOR inhandle_params.The golden rule is: always load data on mount. But if you add live navigation with
live_patch, the data that can be changed on-the-fly must be now loaded onhandle_params.ydd
Hey José,
Thanks for your reply, that makes sense.
Do you have any advice on which of the two lifecycles the loading should occur? As in the initial HTTP connection versus the websocket connection?
I’m having trouble rendering “static” HTML that has meaningful content but avoiding loading the content twice. Feels like the first HTTP connection should render a simple “loading” markup and branch on
socket.connected?and perform the loading then.LostKobrakai
If you want SEO and/or a working website without javascript you’d need to load stuff for both renders. The HTTP request and the websocket connection are completely separate connections (by time as well as type) so you cannot simply keep state around on the server. If those points are not relevant you can just load stuff for the websockets connection and make the static render return just a loading screen.
ydd
Hi @LostKobrakai, that makes a lot of sense, thanks for the clear explanation.
stefanchrobot
Fair points! I think this could be mentioned explicitly in the docs (unless I missed it). I might be mistaken, but it seems people are using LiveView mostly for web apps where SEO doesn’t matter.
@josevalim writes about a simple technique to load everything once here.
LostKobrakai
It surely depends on the content. For many web-applications even a non-interactive static response can be useful in the face of e.g. some failures for the js/websocket stuff. If we’re talking e.g. about games though the static render alone doesn’t hold much usefulness.
stefanchrobot
Not sure if that’s one of the intended usages of LiveView, but if it were to be used as a replacement for SPAs, then the static render isn’t really useful, except maybe for a loading spinner. (BTW now that I think of it, the socket assigns can grow a lot if not enough care is taken.)
LostKobrakai
I’m of the opposite opinion. Often times SPAs are used because the page needs e.g. live update or lazy loading of a list of items. If things start to fail on the client side (for whatever reason) you’re often left with nothing. Many of them could show a lot of useful information if they would have a static render or even fall back to e.g. plain old pagination links if the fancy js lazy loading does fail.
ydd
All SPA frameworks offer server-side rendering precisely to have meaningful content on first page view. Not only for SEO but also, as @LostKobrakai mentions, to allow graceful degradation into a partially functional application.
I guess it depends on the type of app you’re building, but I think most apps should try to return content on first page render.