thiagomajesk

thiagomajesk

What strategies are you currently applying to reduce the amount of code inside a LiveView?

For the past two to three weeks I’ve been working with LiveView in a side-project and one thing that I’m noticing so far is that my LiveView code is getting “bloated” very quickly.
Since I’m working with one LiveView as the single source of truth and a lot of LiveComponents which are constantly pushing state updates, I’m handling all of this information flow in a single place - the LiveView.

That being said, I was wondering what strategies are being used by the community to improve this…

One of the things that I was thinking is: creating a live/handlers folder and place modules that will concentrate the logic that manipulates the information there; letting the LiveView code exclusively to receive the events and call those modules, akin to the “thin controllers & fat model” approach. Has anyone tried something like this?

Most Liked

Menkir

Menkir

For me it was building reusable components. It’s a bit harder to design such a component to be that flexible but in the end it helped me a lot reducing code. It’s also simpler to test and maintain. At least for the Frontend there is a WIP library Surface which tackles the problem.

One other thing is to split the concerns. The UI related code is handled in each component while the parent LV is handling only the relevant information of the application. And there you can also split the callback algorithms (logic) in discrete Modules which you can reuse in other Projects.

Hope I could help.

thiagomajesk

thiagomajesk

Hey @Menkir! I heard about Surface before, but haven’t tried using it yet. I’ll keep exploring LV until I seed the need to use another abstraction on top of it.

How are you making the distinction between “UI related code” and “relevant information of the application” in your LiveViews? For my scenario, there’s constant communication between the LV and the LiveComponents which compose the LV state. So, everything inside the LV is already part of the UI and the “relevant” portion is handled by application contexts.

What are you defining as “page behavior” for your application? Thanks for the reply!

Hi @bluejay! I haven’t heard of your lib before, I’m definitely gonna check it out. Are you using it in production? If so, what major gains have you noticed so far?

@tfwright I’m also doing the same thing as you - all of the events are handled inside the components, but since I have to keep the main LiveView up-to-date when changes happen, I also have to handle a lot of events in the LV itself, mainly regarding the LV state (idk, perhaps I should break things in more components).

bluejay

bluejay

Yes, using it in production and the major gains from my standpoint are as follows (for simplicity I am using the word module to refer to LiveViews and LiveComponents)

  1. By declaring all my assigns (as props or state) at the top of my module, I can see at a glance what data the module needs to function. I also have an easy place to look when I can’t quite remember what I named a particular assign)
  2. By declaring default/initial values, I can greatly simplify my mount/update callbacks for modules that have a lot of state (or even bypass them entirely)
  3. Props are automatically added to a LiveComponent’s module documentation, so I can easily see what props a LiveComponent expects without navigating to and opening the file.
  4. Setting props as :required will raise errors if those props are not passed in to a LiveComponent, which helps spot errors more quickly
  5. If i have “computed props” inside a LiveComponent, those will be refreshed whenever the props are updated. For instance, the following snippet is for a LiveComponent that expects as :user_id to be passed in, which we use to fetch the user from the database. Anytime the :user_id changes, :user will be refreshed. Again, this saves me from having to write my own update callbacks.
use Phoenix.LiveComponent
use LiveProps.LiveComponent

prop :user_id, :integer, required: true
prop :user, :struct, compute: :get_user! 

def get_user!(assigns) do
  Repo.get!(User, assigns.user_id)
end
  
 # ... rest of LiveComponent

Where Next?

Popular in Discussions Top

thojanssens1
It would be nice to be able to define a redirect from one route to another from the router.ex file. E.g.: redirect "/", UserController, ...
New
AstonJ
I’ve just started the Phoenix part of the utterly brilliant online course by @pragdave. On generating the Phoenix app he uses the --no-ec...
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
rower687
Hi all, I’ve been reading a lot about the “let it crash” term and how supervising processes and the whole messaging passing make an elixi...
New
jer
I’ve been using umbrellas for a while, and generally started off (on greenfield projects at least) by isolating subapps based on clearly ...
New
PragTob
Hey everyone, this has been on my mind for some time and I’d love your input on it! TLDR: I feel like maps are superioer for storing and...
New
eteeselink
Hi all, In the last days, two things happened: A blog post titled “They might never tell you it’s broken” made the rounds. It’s about ...
New
MarioFlach
Hello, I want to share a project I’ve been working on for a while: https://github.com/almightycouch/gitgud Background Some time ago I ...
New
jesse
Hi everyone, I hesitated to post this here because I don’t want you to think I’m spamming, but I’ve been working on a Platform-as-a-Serv...
New
axelson
Decided against including more info in the title, but the gist is that Plataformatec sponsored projects will continue with the assets bei...
New

Other popular topics Top

sen
Hi All, I set a environment variables in dev.exs , like below code. when i start server, how can i set the ${enable} value? thanks. d...
New
danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29603 241
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement