Post-mortem: Lucidboard for Hack Week

For our QL Hack Week, we began connecting the new and exciting Phoenix LiveView (github) library into our Lucidboard project. LiveView is allowing us to very rapidly wire up interactive user experiences by simply writing a bit of event handling code which updates the client's state. The technique employs websockets which hold the client's state on the server end, keeping everything scoped to a single application, and hugely simplifying the development process.

We were having great successes right from the start, and by the end of the week, the team was very jazzed about what the new approach could mean for the historically daunting task of building with a JavaScript framework like React or Angular.

Take for example the "like" button on a Lucidboard card. To implement this feature, we needed to do two things. First, we indicate to LiveView that we would like to send an event when the user clicks the heart icon, sending the card's id as a parameter in the view template:

<a phx-click="like" phx-value="<%= @card.id %>" href="#">
    <%= fas("heart") %> <%= length(@card.likes) %>
</a>
        

Then, we handle the event in the LiveView module:

def handle_event("like", card_id, socket) do
  live_board_action({:like, id: card_id, user: user_id(socket)}, socket)
  {:noreply, socket}
end

In this case, we've simply executed the action against the running board and returned an unmodified state. The user will get the same board-update broadcast that all other users looking at the board will get which will increment the like count on the card. Whenever the board updates, all users looking at it will receive the event. It looks like this:

def handle_info({:board, board}, socket) do
  {:noreply, assign(socket, :board, board)}
end

Underneath, whenever this state (stored in the socket) is updated, the templates re-render, and only the updated placeholders get pushed down to the client over the websocket connection. The client side then is using the pre-existing, open-source morphdom library which LiveView leverages to do an efficient patch on the DOM to bring it up to date. Chris McCord & co. have demonstrated how all of this is so robust and efficient across the board.

Even as we went deeper, we found the patterns Chris has introduced with this library very logical, simple, and easy to use, and I imagine teams needing to build these single-page app experiences would be well-served to look closely. I'm really looking forward to using it more and learning further where the pitfalls may be and how it can super-charge my projects.

Show Comments