My Phoenix Live View Migration Experience - Share Yours

I want to thank everyone in our community. Phoenix is rapidly evolving and I like the way it is moving forward. I am using phoenix 1.6 and phoenix_live_view 0.18 . This post may not be relevant say after a week :smiley:.

I have migrated an old controller based project to phoenix live view. This project is an admin console application.

Good things first:

  1. All the controller, view, template hell is gone. Bye bye - I wont be missing you.
  2. Javascript dependency is minimised. I don’t use any javascript library except what is included in LiveView.
  3. Components and change tracking make many things trivial.
  4. Mixing eex and heex frankenstein is being tamed in newer versions.
  5. :if and :let are good additions.
  6. Tailwind and es_build are awesome.

mix helpers generate a lot of boilerplate code. They help in scaffolding a project quickly. But they weigh you down with the debt you have to pay every time you open a file, refactor, etc.

  • Most of the form :live_components are filled with boilerplate where only few things change like schema, context, etc - around 60 lines of boilerplate code in every form :live_component
  • Context file is generated with schema as suffix for list_, change_, create_. This added cognitive overhead while changing form :live_components.
  • Missed server side field change listeners in form components like when a field changes do something on the form :live_component. I don’t want to get into javascript based.
  • I ended up with repetitive code while implementing some patterns in UI Pages.
  • Ecto.Changeset.cast does not give any information discarded changes due to validation failure. In the form we will be seeing invalid value - but we can’t get that information from current changeset.
  • Ecto.Changeset.cast does not include a field in changes if field is changed back to original value present in row. This might be correct in a way - but if you want to do listen on field changes in validate event, it makes your very difficult.

I solved these:

  • by implementing a high level :live_components like form_component, form_with_items, etc.
  • Implementing a slightly different context file - it has uniform names - all_rows, get_row!, change_row, etc

I want to hear more from you:

  1. Did you face similar problems or different set of problems, how did you solve them or am I missing something?
  2. Do you use default helpers or write these files your self?
  3. Please share your Live View migration experiences
  4. Do you use any libraries on top of LiveView?
  5. Do you use javascript in form change listeners ?
  6. Anything…
1 Like

I unfortunately don’t have much here to share personally. I’m lamenting that a few weeks ago I saw a blog post that aggregated a number of LV updates to 0.18. It pointed to projects like live_beats, a few other high profile projects and a few personal ones. If it came from this forum it would’ve been a link because I swear I’m remembering someone’s personal site, not the plethora of Elixir forum, StackOverflow or newsletters. My browser history has been no help but I’ll try to use this post as a reminder to find it because it was extremely helpful, even from an outsider’s perspective.

1 Like

My opinion on any code scaffolding is reserved. I run the phx.gen for every major revision of Phoenix, see what the framework author suggested as the best practices, paste the part I like into my code and discard the rest.


I’ve definitely been caught thinking I could keep updating a changeset but I now know better. I keep the original data around and create a new changeset each time. I’m not the only one who’s fallen into this trap.

I ran the generator once to see what it did but have written it all by hand since. Same for regular controllers, not that I have many.

I use Surface on top of LiveView and a bunch of JavaScript libraries for things like drag and drop, charts, sliders.

I don’t use any JavaScript form change listeners. My app runs on a local intranet so latency is not an issue for me. Are you referring to checking the format of an input on the front end?

There is the initial work of learning the lifecycles of views and components (I copied a bunch of notes as comments into each file until I remembered it). Most of the challenges I face are around my lack of experience with the web in general, e.g getting the bloody layout to do what I want. Being new to web development, I find working on liveview easier than MVC because there are less files/context switching. It’s a bit more of a free for all. Definitely got myself tangled up trying to keep state in the liveview and in Alpine code, but I’ve ripped all that out.

1 Like

Field change listeners or Value change listeners are invoked when something changes on the client side.

Field change listeners come in handy for:

  • enable/disable fields based on user input field like a checkbox, select items, etc
  • when one select field is dependent on other one - refresh dependent select items
  • show or hide parts of form based on user input field
  • set a calculated field based on user inputs in multiple fields
1 Like

I have open sourced a small forms library from this project - Indy Forms - Simplify Your Forms - #6 by kartheek