Zesky665
Drab tutorial error
Hi everyone,
I’m going through the tutorial for drab and got to the case example. After copying the code from the example to my own files, I ran iex -S mix phx.server and visited localhost. When I clicked the uppercase button, I got the following error :
[error] Drab Handler failed with the following exception:
** (Protocol.UndefinedError) protocol Enumerable not implemented for nil. This protocol is implemented for: DBConnection.PrepareStream, DBConnection.Stream, Date.Range, Ecto.Adapters.SQL.Stream, File.Stream, Floki.HTMLTree, Function, GenEvent.Stream, HashDict, HashSet, IO.Stream, List, Map, MapSet, Postgrex.Stream, Range,Stream
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:141: Enumerable.reduce/3
(elixir) lib/enum.ex:1919: Enum.reduce/3
(drab) lib/drab/live.ex:968: Drab.Live.decrypted_assigns/1
(drab) lib/drab/live.ex:958: Drab.Live.decrypted_from_browser/1
(drab) lib/drab/live.ex:918: Drab.Live.assigns_and_nodrab/1
(drab) lib/drab/live.ex:574: Drab.Live.do_poke/5
(drab) lib/drab.ex:359: anonymous fn/7 in Drab.handle_event/6
Anyone have any idea what this is and how to fix it?
Most Liked
Zesky665
index.html.drab was the answer.
grych
There are two types of standard payload sent from the client to to handler - information about the sender, so the object on which the event was launched, and internal data, specific to the used module - like, in this example, drab_index which is used by Drab.Live.
Considering this, exec_elixir should send the module-specific data. This is what I would expect. So I will update it, as https://github.com/grych/drab/issues/174
grych
I believe I’ve fixed this issue, now module-specific assigns are being added to assigns. Expect the fix in 0.10.0, coming very soon (maybe today?)
grych
Actually, in this case Drab should show the better error message. I’ve added the nil case to assigns function, and now:
iex(20)> poke socket, something: 42
** (ArgumentError) template `main` not found.
Please make sure this partial exists and has been compiled
by Drab (has *.drab extension).
If you want to poke assign to the partial which belong to
the other view, you need to specify the view name in `poke/4`.
(drab) lib/drab/live.ex:1005: Drab.Live.raise_partial_not_found/1
(drab) lib/drab/live.ex:878: Drab.Live.assigns_for_partial/5
(drab) lib/drab/live.ex:588: Drab.Live.do_poke/5
piex
Ran into this error message when upgrading from 7.2 to 9.3 and a quick search brought me here. Error is
(ArgumentError) template `main` not found.
Please make sure this partial exists and has been compiled
by Drab (has *.drab extension).
If you want to poke assign to the partial which belong to
the other view, you need to specify the view name in `poke/4`.
(drab) lib/drab/live.ex:1014: Drab.Live.raise_partial_not_found/1
(drab) lib/drab/live.ex:890: Drab.Live.assigns_for_partial/5
(drab) lib/drab/live.ex:600: Drab.Live.do_poke/5
At first I was confused because I was calling poke/2 not poke/4 but after a bit of investigation I see that poke/2 ends up at do_poke/5 using a template id held in socket.assigns. It looks like something is clearing __drab_index: as it goes from __drab_index: “gi2dqnbygazdenbv” to __drab_index: nil in socket.assigns.
I suspect it is an exec_js call I use in the page_loaded callback:
{status, return_value} = exec_js(socket, "navigator.geolocation.watchPosition(function(pos){Drab.exec_elixir('position_changed', {\"lat\":pos.coords.latitude, \"lon\": pos.coords.longitude});}, function(err){}, {});", timeout: 1000)
The solution for me was to use peek/3 & poke/3 to be explicit about the template I want in the poke/peek calls instead of counting on the value to stay clean in assigns.
If I can isolate/verify that the cause of __drab_index getting reset to nil isn’t something in my code I will report it as a bug on github, but thought I would leave a quick note here in case I don’t get to that soon and others run into a similar issue.







