Programming Phoenix Liveview

A few years ago I had read about Elixir but didn’t get very far. This year I was determined to take another look. I had seen a bit on LiveView on YouTube and decided that’s where I wanted to start. At Prag Prog I found Programming Phoenix LiveView by Bruce Tate and Sophie DeBenedetto. It’s still in beta, but I’ve always had good experiences with Prag Prog books.

programming phoenix liveview book

The Experience

This book was a wild ride for me. Still new to Elixir, I had a lot of “wow, this is different”, “wow, this is so cool!”, “oh, this is elegant”, and several “hmm, this isn’t working for me” moments.

Some of my frustrated moments were due to the usual missing punctuation (in my code) and things being new to me. Several others were due to this being a beta book and my feeling that LiveView has been iterating quicker than Bruce and Sophie can keep up with the changes. Re this: I noticed they had a major update to the book in February and LiveView hit back with a big update in March!

This excerpt shows several things I learned:

def handle_event("​​guess", %{"​​number" => guess}, socket) do​​
  message = "​​Your guess: ​​#{guess}​​. Wrong. Guess again. "​​
  score = socket.assigns.score - 1

  {:noreply,
    assign(
      socket,
      message: message,
      score: score)}
end

In this example:

  • Pattern matching — There are several handle_event/3 functions, but this one only matches a message “guess” coupled with a map containing a key “number”. Without those conditions there is no match. The case logic is in the function header, not the function body.
  • String interpolation — Standard yet elegant: more than a simple variable insertion, the #{} construct inserts the result of the evaluated statement.
  • Pulling parameters nested inside arguments — We assign guess to the value of the key “number” inside the map passed in. Slick!
  • Functional programming — No side effects occur in this function. We get data in, transform it, then pass back our changed copy.
  • Tuples as returns{:atom, data} is a prevalent return pattern that gives a lot of flexibility to function returns. Once I learned how these returns are pattern matched themselves my mind expanded a little.

My Takeaways

I really enjoyed learning LiveView. I’ve never been a web developer, though I’ve dabbled with PHP and Rails a bit in the past, and this framework just clicked with me. LiveView is very conceptually simple: mount to set up data, render to create the output, handle_event to respond to changes. In between you have assigns to pass around data between components. Changes to socket will cause a re-render.

A few things made LiveView click for me:

  • CRC — Constructors, Reducers, and Converters
  • Separation of concerns — very MVC-esque. Here’s the view code, here’s the model, here’s the glue.
  • assigns to pass around data for CRC. No need to pass varying numbers of individual variables and assigns works great with transformation pipelines.
  • socket — Merely updating things inside socket will cause the framework to react and update the view. We don’t need to call a bunch of functions ourselves.
  • Tailwind — Super easy peasy, lemon squeezy even for a novice.
  • JavaScript free (for me) — I know there’s some Javascript, but none that I need to deal with for the basics.

Conclusion

This book was a nice introduction to LiveView. Despite its beta status, it did a good job teaching the subject and anything “wrong” is just a temporary misalignment of the current framework and the framework at the time the book was last updated. As stated earlier, Pragmatic Programmers always delivers with beta books.

I am looking forward to writing something more substantial with LiveView. The framework is super pleasant to start with, but doesn’t let me down as soon as I leave the intro tutorial. Even if I don’t end up doing much LiveView in the future, the patterns it uses and corresponding insights into Elixir will serve me well.

See also