Handling reconnections on a LiveView without losing page state

What is the pattern for handling Phoenix socket reconnections on LiveView pages?

It hasn’t been a serious problem for me, since my LiveView pages tend to be “use it right now” and not left open overnight or anything, but I notice that when I do leave my pages open for a while (overnight), reconnections happen and the LiveView pages lose their state.

For example, if I have a button that populates a list that I assign to the socket and render in the LiveView template - if I hit the button, see the list, walk away for a few hours then return… the page has been reset to its initial state.

Am I doing something fundamentally wrong, or is this expected behavior?

Is there an easy fix? I guess I could save a copy of the socket’s assigns for the user whenever the state is changed, but that seems cumbersome.

Thanks!

Trying to keep a process and its state alive, even while the user is disconnected, seems more cumbersome than just saving the state to the database and loading it again when the user comes back. What if the user doesn’t come back to the page for 7 days, or a month, or ever? You wouldn’t want to keep the process alive for that long. (Remember each LiveView gets its own process)

But the user isn’t really disconnected. Suppose the page is showing monitoring data for a server where there’s no constant user input, but there’s a need to have the display settings maintained through spurious browser reconnects?

Typically, javascript client frameworks I’ve worked with handle reconnects seamlessly in the background without dumping state.

But if this is expected LiveView behavior, then okay. I’ll work around it if I need to.

Thanks

I had the same problem and thought of two ways this could be done client-side:

  1. Have the actions that were executed be stored in a cookie
  2. Use a form and then form recovery on phoenix liveview.

I opted for the second and it seems to work pretty well aka. I stopped getting complaints about how people lost their work/state.

2 Likes

I saw the form recovery docs, and wasn’t sure it applied that well since I don’t even always have an actual form element on my LiveView Pages. I’ll play around with it, though.

Thanks

Depending on the use case, another possibility is keeping the state in URL params. So if, like your example, you are just toggling a list shown or hidden, you could use live_patch e.g.

<%= live_patch "Show list A",
      to: Routes.live_path(@socket, MyAppWeb.PageLive, A: "show") %>

and handle_params to change the state

def handle_params(%{"A" => "show"}, _url, socket) do
  # Stuff
  {:noreply, socket}
end

and the Stuff would be reloaded on re-connect.

1 Like