grych / drab

Remote controlled frontend framework for Phoenix.

Home Page:https://tg.pl/drab

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`broadcast_poke` error while sending to something else than a socket

grych opened this issue · comments

iex(6)> broadcast_poke same_path("/tests/live/mini"), color: "red"
** (ArgumentError) argument error
    :erlang.apply("same_path:/tests/live/mini", :assigns, [])
    (drab) lib/drab.ex:646: Drab.get_view/1
    (drab) lib/drab/live.ex:441: Drab.Live.do_poke/5

This is because Drab.Live in general requires connection to the browser, as it is getting the current assigns from there.

There are three available solution for this

  1. Remove broadcast_poke. Initially, I did not plan to implement it, changed my mind because of #60

  2. Allow broadcast_poke only with connected socket, create a good error message and fix a documentation (remove "all broadcasting functions may have socket or... as an argument").

  3. While broadcasting to non-socket, force to provide all the assign values. In this case there is no need to read the assign values from the browser.
    The only thing is a problematic API, we need to provide the list of other assign values somehow.

broadcast_poke same_path("/"), color: "red", using_assigns: [text: "text",..]

But in this case you can't name you assign @using_assigns :) Any other suggestions?

Personally, I like 1st solution the most :) But 3rd may also do the trick, with good error message when not all the assign values are provided.

Additionally, we could implement 3rd solution also in poke - if you provide all the values there is no need to read it from the browser, which improves the performance, especially when having partials with one assign only.

Actually, without a socket you will be forced to give also a view and a template, as it could not be determined automatically without a socket.

broadcast_poke same_path("/"), MyAppWeb.MyView, "index.html", color: red, using_assigns: [text: "..."]

I've tried to broadcast_poke/4 to a topic instead of a socket, passing all the assign as suggested

defmodule MyApp.MyCommander do

  broadcasting("foo")

  defhandler do_broadcast(socket, _sender) do
    broadcast_poke("foo", MyApp.MyView, "_my_partial.html", using_assigns: [test: 42])
  end
end

but I'm getting this error:

12:52:05.329 [error] Drab Handler failed with the following exception:
** (FunctionClauseError) no function clause matching in Phoenix.Token.get_key_base/1
    (phoenix) lib/phoenix/token.ex:192: Phoenix.Token.get_key_base("foo")
    (phoenix) lib/phoenix/token.ex:111: Phoenix.Token.sign/4
    (drab) lib/drab.ex:578: Drab.do_push_or_broadcast/6
    (drab) lib/drab.ex:512: Drab.push_and_wait_for_response/5
    (drab) lib/drab/live.ex:734: Drab.Live.decrypted_from_browser/1
    (drab) lib/drab/live.ex:703: Drab.Live.assigns_and_index/1
    (drab) lib/drab/live.ex:691: Drab.Live.ampere_assigns/2
    (drab) lib/drab/live.ex:657: Drab.Live.assign_data_for_partial/4

12:52:10.333 [error] Process #PID<0.3943.0> raised an exception

Hey, this is not done yet :) I am working on this. Hold on until I close this issue