jeffrey
How to enforce Drab to reload full loop?
Hello.
I use Drab and I want just to change the value of assign inside of a loop.
I have this loop code:
<%= for page <- @holder.pages do %>
<%= if page.id == @page_id do %>
<tr>
<td><%= page.title %></td>
</tr>
<% end %>
<% end %>
I change @page_id like this:
Drab.Live.poke(socket, page_id: id)
This function called when clicking on a button.
Everything works just fine when I place @page_id on some static element like h1.
But it doesn’t work inside of the loop.
Error: undefined function page/0
Can someone explain me why does it happen? I think Drab doesn’t fully reload loop - only if expression.
Marked As Solved
grych
Unfortunately, it is not a bug. This is a limitation of Drab.Live’s local variables scope && the way how Drab is replacing parts of the page with the evaluated expression with new assign values.
When you’re poking the new version of assign @page_id, Drab tries to update it in every expression on a page, which contains that value. In this case, it is if page.id == @page_id, do:.... But in the particular moment it does not know the value of page variable - that’s why it shows undefined function page() while evaluating this expression.
It is done by purpose. I could search expressions for assigns in their do..end blocks, and re-render the the whole for comprehension while changing @page_id. And actually it was made like this before, but I realized that in the real world it provides to full reload of almost the whole page and more issues, like #42.
In this particular situation, when you poke @page_id, you really want to update the whole for compehension. One of the solution would be to put @page_id assign in the comprehension filter:
<%= for page <- @holder.pages, page.id == @page_id do %>
<tr>
<td><%= page.title %></td>
</tr>
<% end %>
This moves @page_id to the for expression, and now, after you poke it, it re-evaluates the whole one.
I know it is not very intuitive, but so far I couldn’t find the better solution.
Anyway, please create an issue on github, this situation needs more explanation/docs and/or at least the better error description. Probably it should not even compile.
Also Liked
jeffrey
I tried to place this loop logic to commander function like this:
holder = peek(socket, :holder)
page = Enum.find(lesson.pages, fn(p) -> p.id == id end) id end)
poke(socket, page_title: page.title)
But I got nil instead of page.
I have no idea what’s wrong with this code. I tried a lot of tricks and workarounds.
OvermindDL1
grych
Hi @OvermindDL1, thanks for waking me up from my winter hibernation ![]()
Hi @jeffrey, I will take a look and will get back to you. It might be a limitation of how Drab is processing the code blocks (inside do…end), I am not sure if it is properly documented (here).
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








