jberling
How do you debug state changes using LiveViews?
I’m developing a LiveView with a somewhat complex, nested state. I’m encountering a strange bug: When handle_event is called for some events, the socket argument is filled with stale data. I find it hard to debug, as the machinery behind LiveView is pretty opaque to me.
I have struggled with this for half a day, or something like that, and feel like a junior developer again ![]()
Now I wonder: how do you debug LiveViews? Are there any tools one can use?
Can I inspect the state? Since I’ve encountered a bug that seems to indicate stale data, where can I inspect the stored data? If, indeed, data is stored in several places, where? Is it stored in the view hierarchy somehow?
Another possibility is that the data is updated before the event handler with the “stale” data is
called. But I have not found any indications this is the case.
I can’t show you all the code, but below are the parts of the LiveView structure that I think are important.
def render(assigns) do
~H"""
<main>
# Could this be the source of the problem? I've thought of putting the answer_editor in a LiveView component
# in some kind of shotgun debugging fashion. I have no idea why it would help, but maybe it would be easier to debug
# since I could encapsulate the state changes in the component.
# Or it would be harder to reason around because of the extra complexity.
<%= for qa <- @question_items do %>
<.answer_editor
form={qa.form}
variant={qa.variant}
question={qa.question}
open?={qa.open?}
evaluation={qa.evaluation}
/>
<% end %>
</main>
"""
end
def answer_editor(assigns) do
~H"""
<.simple_form for={@form} phx-change="update_editor" phx-submit="evaluate">
. . .
<.input type="textarea" field={@form[:answer]} phx-debounce="750" />
. . .
<.button name="action" value="evaluate_now">Bedöm</.button>
</.simple_form>
"""
end
def handle_event(
"evaluate",
%{"question_id" => question_id},
socket
) do
# This logs stale data
IO.inspect(socket.assigns.interview.answers)
. . .
end
def handle_event(
"update_editor",
%{"question_id" => question_id, "answer" => answer},
socket
) do
# This logs the expected data
IO.inspect(socket.assigns.interview.answers)
. . .
end
Most Liked
steffend
We should have some kind of warning in the future: complain loudly if LV is initialized twice by SteffenDE · Pull Request #3721 · phoenixframework/phoenix_live_view · GitHub
steffend
The behavior is indeed interesting. What’s going on is that the app.js is executed twice, because it is included twice in the initial render. That causes two LiveViews to be started that both try to control the same DOM and causing a lot of chaos. I’ll think about ways to make that fail in a more obvious way ![]()
dimamik
Have you tried Live Debuger? You can inspect and trace state changes there.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









