grych / drab

Remote controlled frontend framework for Phoenix.

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Does `broadcast_poke` pass "origin" socket's assigns to all browers?

mbaleczny opened this issue · comments

Elixir: 1.7.4
Phoenix: 1.4
Drab: 0.10.0

I want to implement live comments in my blog app using broadcast_poke with socket like:

Commander:

defhandler add_comment(socket, sender) do
  message = sender["value"]
  post = peek!(socket, :post)
  user_id = get_session(socket, :user_id)

  case Blog.create_comment(post, %{user_id: user_id, body: message}) do
    {:ok, %Comment{} = comment} ->
      broadcast_poke(socket, "show.html", comments: Blog.list_comments())
      set_prop(socket, this(sender), value: "")

    {:error, _} ->
      ...
  end
end

show.html.drab:

...

<div class="comments">
    <ul>
        <%= for comment <- @comments do %>
            <li>
                <b><p><%= comment.user.email %>:</p></b>
                <%= comment.body %>
                <div>
                    <%= if show_delete_button?(current_user: @current_user, comment: comment) do %>
                        <button drab-click="delete_comment('<%= comment.id %>')">Delete</button>
                    <% end %>
                <div>
            </li>
        <% end %>
    </ul>
</div>
...

When I add new comment logged as an admin everything is fine, but in other session (no user logged) I got the same result - every comment has "Delete" button. Somehow every browser gets "assings" from browser where admin is logged in. I wonder if this is the correct behavior?
I've tried to figure out what's going on with logs in commander and layout, but with no luck.

Is there any other (simple way) to solve this? I've found article about live comments in Phoenix, but it needs a lot of JS code.

Asshow_delete_button?/2 checks against current_user, the problem seems to be inside that function because @current_user should be different for every user session. Just try to print out its value on your page adding something like <p>current_user: <%= inspect @current_user%></p> and see if you get different values when testing the same page on different browsers (not different windows on the same browser).

Yes, broadcast_poke is tricky and it should not even exist. I should not do it at the first place.

It renders the template against the environment which triggered the change, and the change is propagated to all.

Please use other broadcasting functions, for example from Drab.Element.

I am going to update the documentation with more about broadcast_poke.

Thanks!

I use broadcast_insert now and it's fine. But I wonder if there's a way to "tell" every browser "hey, call handler function which pokes data especially for you" ?

Well, you can broadcast_js with exec_elixir(), but prepare for a huge load :)