So I have a Phoenix function component that I use in a “dead” (classic) view and also in live views. This works great, but the problem is that I also need to add some functionality (toggle a menu) that has to be done client side to be snappy. I want to use JS commands to do this (as opposed to bringing another dep such as Alpine or using vanilla JS), but the problem is that those won’t work in a “dead” view.
Is there any way to use
JS commands and
phx-X bindings in that dead view?
I cannot migrate the dead view to a live view as it deals with authentication (needs to set cookies) so that is not really an option
You can do whatever you want for authentication from a liveview.
Two main techniques:
- Simply have your form do a POST action and set up a post route for your liveview path, then set your cookies and redirect out of there
- Do what you need to do, sign a Phoenix.Token authenticating the user (can contain just the user id, remember to use .encrypt() if you dont want to leak your way to implement it) by doing a redirect() with the token on the path to an auth/login_handler?token=<…>
- I think the live session lib is getting popular? Iirc under the hood it simply signs some tokens and sends an XHR and on that request the cookies are set, personally I think that method is a bit vague, but it does allow you to set cookie session stuff willy nilly for other things too. Personally I prefer to store my page local state in params so that urls and state is always deterministic, way easier to debug peoples problems
I tried that, but I’m stuck at the login part.
For context I’m using phx.gen.auth.
So tried moving the login form to a live view, all works until the time I need to actually login the user (calling
UserAuth.login_user(conn, user, user_params)). Since I need a conn for that, I have to redirect to a dead view (that will call UserAuth.login_user) but the problem is how do I pass the email and password in the redirect to the dead view? I don’t want to make the password part of the URL
I’d suggest letting the form submit directly to a controller and not handling form submits through liveview at all. You can still do error handling on changes through liveview if that’s something you’re after.
Note you can also mix both. You can use live forms for validation and then use
phx-trigger-action to submit the form once it is validated. However, for login, I don’t think there is a useful validation, so submitting to the controller is the way to go IMO.
This from jose is my point nr 1 above
Thank you @josevalim, that was the piece of knowledge I was missing!
Wasn’t familiar with
phx-trigger-action, I’ll give it a try and report back
And yes, for login, I don’t have validations, but the original problem there remains (if I use the dead view with the login form I cannot use a header that needs some JS commands to add UI behavior or resort to Alpine.js or vanilla.js instead)
You don’t need to have both the endpoint, which renders the form as well as the endpoint handling the form input be backed by a controller. You can have the first be handled by a liveview and only the latter by a controller.