Foreword
These were my notes after doing my first 101 LiveView application that was mostly CRUD, shopping list. This is not a criticism to LV but observations and most probably majority of them caused by my inexperience.
Some of them could be solved by external JS tools also but I purposefully didn’t include anything external to see the full power and limitations of LV.
I wanted to share with you, learn from them and hopefully contribute to the community to overcome some of the challenges I have faced or help anyone who is going through the same journey.
When I say wire, I mean the connection and payload, with LV the diff and events that is being sent and received from the client.
Select all checkboxes:
Fairly simple thing in the frontend and optimized payload with standard HTML forms. I have seen solutions to keep track of them on the socket, in order to keep things in sync. You kind of have to keep them in the socket otherwise your checkbox is checked on the frontend for something that is not checked in the socket.
Eliminates temporary_assigns
comes with performance and wire drawbacks as the list grows.
You can’t have form input with multiple submit buttons
You would like the add notes and set the status of an item via different submit buttons. I have searched around and it is not possible with pure LV.
You can’t capture the value of submit
button or the input field(s) if you assign it to phx-click
. If you wrap it in a form then LV won’t be able to track the diff and send the whole form payload every time as well as you would still not know which submit
button was pressed.
To memory or to wire
Either sacrifice memory or wire. assign
or temporary assign
is the problem. Both come with pitfalls.
If you assign, a simple add to favorites can be penalizing and a jarring user experience! In my demo I order the favorites at the top, It is an awful user experience when things move underneath your mouse and your wire loads 100s of entries because you changed something in one of them. You can solve one of them by temporary_assigns
and update
the entries in the socket with phx-update
directive in the html.
Temporary assigns and updating funkiness for delete
You have to do funky stuff with updating to delete things with a minimal wire transfer like
if item.__state__.deleted == true, do: "is-row-hidden"
Form resetting
If you use changesets for your form, your parameters and changesets are not bound since it is a one-way journey, unlike the normal HTML
If you would like to reset your form on successful submission without hacky javascript, you would have to have sacrifice wire and add phx-change
on your forms to validate changesets.
If you do not use changesets, same problem still occurs. I ended up flip-flopping between nil
and ""
on successful form submission.
If you want to preload, cache something in your component once ie: categories for the form…
That has parameter dependency as mount
will get called without any of the parameters you passed.
live_component @socket, MyForm, user: @user
MyForm
mount(socket)
no user to fetch categories for the given user scope :(
The update
will be called with parameters
but in every lifecycle
.
I ended up moving the logic to LV and sending it as a parameter, which meant self encapsulated logic from the component had to bleed into LV.
LC can’t broadcast
I was surprised and searched around, didn’t find anything. I had to send it to LV again, resulting in logic bleeding out to LV again.
Multiple LVs on one page
I have read on the forums people using multiple LVs on the same page but haven’t tried that setup yet. This was more of a 101 attempt for me and that pattern might alleviate some of the problems but brings the question the power of LC, just neat rendering blocks and all the other stuff you use LV?