5 ms·
Phoenix LiveView: Async Assign Pattern
- gnutrino 3y agoI started using this pattern in my LiveView projects, and finally rolled it into a common module for others to use. I've found it really helps clean up the mount function, which can get pretty messy as your LiveViews grow over time. My apologies for the terrible elixir syntax highlighting in this post. I keep putting off finding a good way to do this on Blogger.
- conradfr 3y agoAre you sure your import should not be: import Phoenix.Socket, only: [assign: 2, assign: 3]
- gnutrino 3y agoI believe you are correct. I could probably remove the imports altogether, and just prefix those functions with `Phoenix.LiveView`.
- sodapopcan 3y ago+1 for removing imports! Not that importing is useless but single-use imports drive me a bit nuts. Even just using it a few times. It's nice to be able to jump to some code and know exactly where everything is coming from without having to jump around the file.
- barkerja 3y agoKnowing the origin of the function is a huge benefit, but also imports create compile time dependency. In this case, it's not an issue, but when you're importing a lot of things across your codebase, it can become an issue.
- sodapopcan 3y agoYa, if you design relationships as a DAG then those sorts of compile time dependencies don't matter. Of course sometimes it can't be avoided (Phoenix router, ecto relationships) the router isn't updated very often and schemas don't have too far a reach (at least they don't if you keep them in their contexts). I don't avoid import but I generally I strive to import one module where I'm going to be using many functions. I rarely bother with `only` unless it's absolutely necessary due to conflicts otherwise specifying `only` is a good indication I don't even need to import.
- nivertech 3y agoI'll take compile-time dependency over unchecked run-time dependency (almost) every time!
- sodapopcan 3y agoWhen using LiveView I always use: import Phoenix.Component, only: [assign: 2, assign: 3] https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#assign/2 https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#... Importing from Socket should work, but you're right, the code in the post wouldn't work. They use to be in LiveView but got moved to Component.
- gnutrino 3y agoI'm still on 17.X, so that probably explains the discrepancy here. I think I tried doing a major version bump a while back and things didn't compile so I put it on the backlog and forgot about it. It may be time to revisit before I get too far behind.
- vinnymac 3y agoI haven't written Elixir professionally the last couple of years, but I was an early user of LiveView when it was first demoed at a conference. As someone who currently writes applications using React Server Components, I am interested to see how concepts like LiveView evolve over time. We are now shipping significantly more HTML than before, and a lot less Javascript, as more has been moved to the server. Makes me wish LiveView was portable to every other platform I work on, rather than having to convince companies to write more Elixir (although that isn't a bad thing).
- nocsi 3y agoThere's https://native.live https://native.live if you want to deploy it as a native app. You can also embed React Components into LiveView if you wanted. Elixir can be anywhere you want it to be.
- gnutrino 3y agoI haven't looked into this much, but saw someone do a talk on it at ElixirConf maybe two years ago. I bet it's much more robust now.
- floodfx 3y agoThere is a port of it to JavaScript/Typescript. https://LiveViewJS.com https://LiveViewJS.com It uses the same front end javascript from Phoenix and speaks the same protocol. Note: am author
- golemiprague 3y ago[dead]
- jjdeveloper 3y agoDoes this work with Astro (or Next.js)?
- nhumrich 3y agoYou could look into htmx, which is a more language agnostic way to do it.
- tommica 3y agoLooks really useful and neat especially the way it chains so fluently for parallerization
- gnutrino 3y agoAs I evolved the pattern over time, I found it really did help clean up a lot of code in `mount`. Once I got it working for one LiveView, it was really easy to rip out a lot of messy code in the other LiveViews. I'm definitely happy with the results! Thanks for reading.
- wahnfrieden 3y agoAnyone doing similar with Swift given it also has server continuations?
- social_ism 3y ago[dead]
- ramchip 3y agoDoes this work well with tests? For instance, if you click a button in a test, do you need to do something special to ensure the async update has happened before checking assertions on the HTML contents?
- msmithstubbs 3y agoYes, LiveViewTest (a module included in Phoenix LiveView) supports testing connected mounts. You can write a test that just fetches the disconnected state, and then upgrades it to a connected state (see https://hexdocs.pm/phoenix_live_view/Phoenix.LiveViewTest.html#live/2 https://hexdocs.pm/phoenix_live_view/Phoenix.LiveViewTest.ht...). If you want to test the result of a button click there's support for that, too, with things like `render_click`.
- ramchip 3y agoI mean for async assigns specifically. I did something like this in the past and had some troubles with render_click returning the html before the async update completes.