Phoenix_live_view: Revamp handle_params

Created on 28 Oct 2019  路  18Comments  路  Source: phoenixframework/phoenix_live_view

Today there is an ambiguity on live_link. Does it reload the page? Does it update the current view?

We think it would be best if live_link is used exclusively for navigation and across different live views and if you want to change the current liveview, you use live_patch. We will also change mount/2 so params are once again passed on mount and handle_patch is necessary only if live_redirect or live_patch are used.

PS: handle_patch is just a tentative name. We may call the new function live_params and keep the callback has handle_params.

Most helpful comment

We have updates on all of the actions to fix this issue:

  • mount/2 will be renamed to mount/3 and accept a params option. The params option will be the atom :not_mounted_at_router for any child LiveView or LiveViews not mounted at the router.

  • handle_params will continue as is. live_link in .leex will become live_patch for invoking handle_params without remount. live_redirect will be added to .leex for invoking handle_params after mount.

  • The .leex API will be mirrored on the server. push_redirect will be for remount. push_patch will be added for handle_params.

  • We will introduce LiveView.Helpers to encapsulate all .leex functions (instead of a huge import)

In a nutshell, the workflow is:

  • If the params have to be loaded on mount, use live_redirect
  • If the params are simply customiznig the current page, use live_patch

I will start working on it this week.

All 18 comments

I definitely like the idea of a function that can be called to simply adjust parameters. If there's one upside to the current handle_params functionality though it's that, both on mount and later if params change, you generally want a function that takes a set of params and puts stuff on the socket. That is to say, if params are passed in on mount, and there is also handle_params, you'd probably end up writing some third function that you called from both to apply params to the socket.

However, the "special" character of handle_params, where it was the only handle_ function called before the first render has always felt weird.

@benwilson512 we are not quite sure yet if the function will accept only params but the idea is to have a clear distinction between things that are meant to change the current LiveView and general navigation.

Also, the reason params will be sent both to mount and handle_params (or handle_patch) is to have a distinction between which kind of params you actually want to be updatable. For example, for /posts/1?sort=desc, you likely want a separate ID to be fully handled by another instance of LiveView, so that is static (mount) but sort is updatable (dynamic).

I agree with that distinction. When you say "the reason params will be sent both to mount and handle_params" to which params are you referring? path_params? query params? both? Today mount gets path params, handle_params gets query params. Is this proposal that mount would get both path params and query params, and then subsequent changes would go to only handle_params?

IIRC mount gets no params today. In the proposal, mount would get connected_params + path + query params, so any param you don't expect to change is loaded on mount, and all others in handle_params.

With live routes, if you do session: [:path_params] on the live route you get a path_params key in the first arg to mount containing the path params.

I see the point in passing in all params to mount though since there may be query params you want to treat as locked as well. Would handle_params in this proposal still be called after mount before the first render?

With live routes, if you do session: [:path_params] on the live route you get a path_params key in the first arg to mount containing the path params.

Ah, doh, I forgot about it.

Would handle_params in this proposal still be called after mount before the first render?

Yes, so it becomes the shared point for all non-locked params.

Great, that would work very well. The only remaining item related to this is: GET forms. Suppose you have a list of things with a filter form. It's of course simple enough with phx-validate to have changes to the form sent to the server so that you can adjust the displayed content. What's less simple though is if you want the search params to end up in the URL so that you can easily copy and paste this to someone else. What you have to do is have the handle_event clause for the form change to do a live_redirect with the params, and then do the actual filtering in handle_params.

The proposed function live_patch or live_params would simplify the live_redirect call in that situation a little, but the ideal solution would be a phx- tag you could place on the form where, instead of the form params being pushed down as an event, they are instead pushed into the query params and handled via handle_params.

This may be orthogonal but it feels related since we're discussing functions focused on query param editing.

@benwilson512 yeah, get forms feel like should be treated as regular links. Definitely orthogonal but good to keep in mind.

I built a DataTable example on this premise, if you want/need something to test against: https://github.com/mcrumm/live_table_demo

We have updates on all of the actions to fix this issue:

  • mount/2 will be renamed to mount/3 and accept a params option. The params option will be the atom :not_mounted_at_router for any child LiveView or LiveViews not mounted at the router.

  • handle_params will continue as is. live_link in .leex will become live_patch for invoking handle_params without remount. live_redirect will be added to .leex for invoking handle_params after mount.

  • The .leex API will be mirrored on the server. push_redirect will be for remount. push_patch will be added for handle_params.

  • We will introduce LiveView.Helpers to encapsulate all .leex functions (instead of a huge import)

In a nutshell, the workflow is:

  • If the params have to be loaded on mount, use live_redirect
  • If the params are simply customiznig the current page, use live_patch

I will start working on it this week.

To make sure I understand a minor nuance here, if I were to go edit the URL in the browser, what happens? Does it always remount or does it depend on the params I edit?

@benwilson512 the browser will know what you did (if it was a redirect/remount or a patch) and act accordingly.

Is this still the case?

In the proposal, mount would get connected_params + path + query params

Otherwise, you also have to create a handle_params just to get the URI.

Yes, if you need the URI, then you will need handle_params.

mount/3 is on master. LiveView.Helpers was already part of the v0.5 release.

push_patch and push_params are on master. Only the work on live_patch and live_redirect for views remaining.

All in master.

鉂わ笍

Was this page helpful?
0 / 5 - 0 ratings