Is there a way to pass a value stored in Phoenix.LiveView.Socket assigns when navigating from one LiveView to another?

Hey all, I’m learning Phoenix and LiveView, and I don’t understand how to preserve a value between live views.

TL; DR: Is there a way to “pass” a value stored in Phoenix.LiveView.Socket assigns when navigating from one LiveView page to another one?

More details: I tried to follow a basic guide and created a Thermostat view with a plus button to increase it’s temperature value. I then created (copied) a separate ThermostatDec view module with a minus button and event handler to decrement value with the same name.

Next, I added them both into my router.ex under

scope "/" ... do
    live_session :live_experiments do
        live "/thermostat", Thermostat
        live "/thermostat/1", ThermostatDec
    end
end 

Finally, I added a <.link navigate=“…”> on both pages to lead from one to another, and replaced last line in mount/3 to :ok, assign_new(socket, :temperature, fn -> temperature end)} on both views.

My assumption was that since both views are in the same live_session, and I’m using assign_new - then upon switching a page I’ll be able to reuse temperature from the last page, but instead I’m getting a socket with assigns: #Phoenix.LiveView.Socket.AssignsNotInSocket<> every time.

So, I wonder - is there a way to carry a value from one view onto another one, or does it make no sense?

I realize I can pass a user_token from phx.gen.auth in session argument, store user’s temperature in DB, fetch it in each mount, and update on every button click, I’m just curious if there is something else that I’m missing.

I would include the current temperature in the URL params of the <.link> to the other liveview.

Alternatively, you can use the same liveview with multiple live_action values. First, by specifying the live_action name in the router:

live "/thermostat", Thermostat, :fahrenheit
live "/thermostat/celsius", Thermostat, :celsius

You can think link between them with <.link patch={~p"/thermostat/celsius"}>, your handle_params/3 callback will be called after the initial mount/3 and with each patch’ing of the URL. You’d check assigns.live_action to know which mode you are in.

3 Likes

There is an open GitHub issue to track this feature request : Allow sharing assigns while navigating between live sessions · Issue #3357 · phoenixframework/phoenix_live_view · GitHub

I would love this feature as well, as it could potentially reduce a bunch of DB loads between pages.

I have no idea if this will become a PR, or if it will be merged it, but we can only hope.

4 Likes

I’d like to have a variation of patch_navigate that can pass along assigns but has a fresh layout. Consider for example separate pages for show and edit, but they work on the same data.

Having to keep these in the same liveview and use conditionals on live_action tends to mix concerns and make for large liveview modules.

For traditional controllers this is less of an issue because we have separate view modules.