Drab: remote controlled frontend framework for Phoenix

I noticed in v0.10.0 Drab is set to require plug_cowboy 1.x – Drab (seemingly) worked for me with plug_cowboy 2.x. Did you find a reason to lock it down to 1.x?

True, should be 1.0 or 2.0. 1.0 is for compatibility with the older versions of Phoenix. I will fix it.


Hey @grych, I’m having issues again with connecting to the topics for broadcasting.

The fixes you originall implemented, that seemed to solve it, are now part of 0.9.3? Just checking they didnt slip out during a commit to the packages.

When i subscribe to a topic in the Drab Commander, should this show in the console logger that they are connecting to the topic, not the path?

here is my callback for onconnect :connected

def connected(socket) do
  subscribe(socket, same_topic(user.id))

But I only see logging that shows connection to the default path.

[info] JOIN "__drab:same_path:/user/dashboard" to Drab.Channel

Out of the blue, i seem to be having the same issues again, where broadcasting to a specific topic is going to multiple browsers that it should not (are not subscribed. e.g:

Drab.Element.broadcast_html(Drab.Core.same_topic(brand.id), "#auction", html)

Is there some way I can check that browsers are connected to specific topics properly? or see when that topic subscription changes. or have I got something wrong with how I am subscribing?

Using iex I can inspect the User socket after the onconnected callback. running that I can see this. Should i be able to see subscriptions to topics here?:

topic: "__drab:same_path:/user/dashboard",


thanks again

1 Like

Dont even worry about me. it looks like i was actually broadcasting to the same topic.
Pro Tip, use unique names for the subscribing to topic, not user ids or numbers which could easily collide. hahah

kill me now.

1 Like

Actually this exact thing seems to still be happening :frowning:

User 1 logs in (subscribe to Topic 1)
User 2 logs in (subscribe to Topic 2)
Event is pushed to topic 1: ok
Event is pushed to topic 2: ok
User 1 refreshes browser
Event is pushed to Topic 1: Both users get the same data

As soon as I refresh one of those browser windows it seems to start pushing messages to both users.

Does 0.9.3 have the fixes in it?

Yes, pls upgrade.


I seem to be getting this error now. and I have no idea how to fix it.

function Phoenix.HTML.Engine.fetch_assign/2 is undefined or private

This is coming from a render function:
<%= render BonusWeb.Staff.OfferView, "_auction_js.html", active_offers: @active_offers, conn: @conn %>

I also get this error during compilation, which is all my drab pages…

warning: function Phoenix.HTML.Engine.fetch_assign/2 is undefined or private. Did you mean one of:

  * fetch_assign!/2

Found at 11 locations:

@grych as soon as I change my mix file to pull in that commit with the fix, it seems to start throwing this error.
Im using this to get the dep:
{:drab, github: "grych/drab", ref: "4ef09e8"},

plsss heellppp

I have tried upgrading everyting to phoenix 1.4, with drab 0.10.0 but i still get the same errrors.
As soon as i rename the index.html.drab file the page loads (without drab).

Please see this issue here https://github.com/grych/drab/issues/180

I dont understand how to lock phoenix_html version.
I have tried override, but it just keeps installing 2.13.1

{:phoenix_html, "~> 2.12", override: true}

I have tried things like == 2.12 but that never works either?
cant find any clear docs on how to do this.

You may do something like

{:phoenix_html, "2.12.0"}

just guessing but maybe a mix deps.unlock phoenix_html and then mix deps.get is needed?

I am publishing v0.10.1 which contains fix for that issue (and many others)

It is Friday evening, and I am at the airport, publishing the release. What can possibly go wrong? :slight_smile:


Is there a way to remove the debug messages “You may debug Drab functions in IEx by… import Drab.{Modal, Element, Live, Core}.etc”

Especially when running in production. its just cluttering up my logging window.

Hi doogs,
it will be solved in the next release. Please be patient.

Hey, If I wanted to add a Drab button to the main layout of my application how would I do that?

The button would be part of the main layout, not part of a specific controller/template.

Does this mean that I would have to create a Drab Commander for all of my controllers, then include the shared Commander on all of those other controllers?

Is there any easier way than that if I want the button to be accessible application wide?

You’d just make that button a shared commander of its own then you can put it anywhere as long as you include the drab system itself and the page itself is drabbed. To be able to drab something you need to initialize drab after all. :slight_smile:

That is easy to automate though with a few macro’s that you can just use into a controller.

1 Like

actually, now rather than having empty string as default, i use “lies:lies” as default for drab attr and it seems fine

1 Like

Hi, just started using drab for some project. i want to dynamically add drab attribute in template (using sigil ~E), like drab="<%= drab %>", however if drab attr is set to “”, ex: < input drab="" >, drab js will throw error, i currently make workaround by having two template, one with drab and one without. is there better solution than this?

TypeError: list is null add_form:1116:19
split_drab_attribute http://localhost:4000/delivery_order/add_form:1116
set_event_handlers http://localhost:4000/delivery_order/add_form:1165
connect http://localhost:4000/delivery_order/add_form:267
value webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
forEach self-hosted:266
value webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
value webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
value webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
e webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
value webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
value webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
decode webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
value webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
onmessage webpack:///./node_modules/phoenix/priv/static/phoenix.js?:1
Source map error: TypeError: bootstrap.js.map is not a valid URL.
Resource URL: webpack:///./node_modules/bootstrap/dist/js/bootstrap.js?
Source Map URL: bootstrap.js.map
Source map error: TypeError: popper.js.map is not a valid URL.
Resource URL: webpack:///./node_modules/popper.js/dist/esm/popper.js?
Source Map URL: popper.js.map

1 Like

Also, sometime when using Drab, i need integration with javascript library (say ag-grid), i do this primarily by calling Drab.exec_elixir from browser side. Sometime i also need to get returned value (say remote data pagination), i currently do this by asking the commander to exec_js which will set corresponding variable with JSON data, then at exec_elixir callback to consume that data. I don’t think this is quite clean, what do you think?

defhandler drab_search_select(socket, sender) do
          "id" => html_id,
          "query" => query_text,
          "var_name" => js_var_name
        } = sender

        data = search_select(html_id, query_text)

        exec_js(socket, "#{js_var_name} = #{Jason.encode!(data)}")

$('#<%= id %>').selectize({
                      valueField: 'value',
                      labelField: 'display',
                      searchField: 'display',
                      options: [],
                      create: false,
                      load: function(query, callback) {
                          //query is a text
                          if (!query.length) return callback();
                          Drab.exec_elixir('drab_search_select', {id: "<%= id %>", query: query, var_name: "<%= var_name %>"}, () => {
                              callback(<%= var_name %>)
1 Like

I’ve just discovered Drab, and it looks amazing, but I’ve hit a wall with the first thing I want to do with it: make dynamic forms. Specifically, I can’t figure out how to poke and peek at the data in a form. Is this possible with Drab?