joaquinalcerro

joaquinalcerro

Drab partials template

Hi guys,

Following up on this github issue where @grych has been kindly helping:

https://github.com/grych/drab/issues/181

I have been trying to get this right but still unable to make it work.

I have the basic controller, commander setup but with nested partials as follows:

Controller renders → new.html.drab template
new.html.drab template renders → form.html.drab template
the form.html.drab template renders → _invoices.html.drab template
invoices.html.drab template renders → _invoice_details.html.drab template

I am setting a drab-change event handler in a input checkbox in the last partial invoice_details.

This event handler triggers a update to a assign (po_grantotal) and this assign is located in the form.html.drab template

This are the form.html.drab template assigns:

iex(6)> socket |> assigns("form.html")
[:action, :changeset, :conn, :currency_us, :invoices, :parent, :po_grantotal]

This is a peek at that assign:

iex(7)> socket |> peek("form.html", :po_grantotal)
{:ok, 0}

So my poke call is as follows:

poke socket, "form.html", po_grantotal: 1000

With this setup I get the following error:

** (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, Scrivener.Page
, Stream, Timex.Interval
    (elixir) lib/enum.ex:1: Enumerable.impl_for!/1
    (elixir) lib/enum.ex:141: Enumerable.reduce/3
    (elixir) lib/enum.ex:1919: Enum.map/2
    (epr) lib/epr_web/templates/payment_order/form.html.drab:76: anonymous fn/2 in EprWeb.PaymentOrderView."form.html"/1
    (phoenix_html) lib/phoenix_html/form.ex:288: Phoenix.HTML.Form.form_for/4
    (epr) lib/epr_web/templates/payment_order/form.html.drab:1: EprWeb.PaymentOrderView."form.html"/1
    (phoenix) lib/phoenix/view.ex:332: Phoenix.View.render_to_iodata/3
    (phoenix) lib/phoenix/view.ex:339: Phoenix.View.render_to_string/3
    (drab) lib/drab/live.ex:683: Drab.Live.rerender_template/4
    (drab) lib/drab/live.ex:638: Drab.Live.process_poke/9

Is this a correct setup? What am I doing wrong?

Thanks in advance for your help.

Best regards,

Most Liked

joaquinalcerro

joaquinalcerro

This is the result:

form.html.drab

<%= form_for @changeset, @action, fn f -> %>
<%= inspect(@changeset) %>
<p>---------------------</p>
<%= inspect(@action) %>
  <div class="row">
    <div class="col-md-12">
      <%= render "_invoices.html", conn: @conn, invoices: @invoices, parent: @parent %>
    </div>
  </div>
    ............

result printed out in the browser page

#Ecto.Changeset&lt;action: nil, changes: %{}, errors: [date: {"can't be blank", [validation: :required]}, concept: {"can't be blank", [validation: :required]}, check_number: {"can't be blank", [validation: :required]}, bank_account_id: {"can't be blank", [validation: :required]}], data: #Epr.Payments.PaymentOrder&lt;&gt;, valid?: false&gt;

---------------------

"/contracts/2/payment_orders"

This is the Google Chrome Console output for _drab

1. assigns:

  1. ge4tcmbtge2dkmzz:

    1. invoices: {document: "QTEyOEdDTQ.rkO2qTvBKpBncBjBOUNNhhYj7hrcS__s-bMZkYU…GoDtSb4T2CJn5yhopxEb6dPUAV.1JZQG4HEUiGSDOPx0Vmdug"}
    2. parent: {document: "QTEyOEdDTQ.Ar-AaS6DIYytU2srD6pveNYKX862GekZZYZ0PAl…g8kxTBr81V7k25jWLuZzcHPZHQ.bftVt5kyWJS067Z4ncibRA"}
    3. __proto__: Object

  2. giytanzzha4tgnjs:

    1. conn: {document: "QTEyOEdDTQ.GFC8HqSwajb9jUthihlg2dc5L5gJj7axH4U1O0H…00URxfOPRo2I9jyO5HmrEEKm8Q.KZim6LitfLrAs4VTTWBtLA"}
    2. parent: {document: "QTEyOEdDTQ.p-wIFXp5VELvZx5v1ub82Zrs3yOt24EWpbsy43s…8h1GOrusAo55428capZCxrT3xs.Yvk7mc9jwyNE0DfhHue51A"}
    3. type: {document: "QTEyOEdDTQ.ckW9WiB7ZPC-4dQtE52IBTBAyHmXC6Gxb40MFNL…5FjoWh.AoPxonuHyD4HuDwBsSc.Ni0NIn9tyrkNjlDlzKJ2qg"}
    4. __proto__: Object

  3. giytkojrgu2tcmbw:

    1. currency: {document: "QTEyOEdDTQ.hQz0cCd0ngRDTKs6mqO8qqBnyDJgOvrM792Xs3y…v3SlJSxT1p6aC.m9923cGIFixp.wQ55dmFJyFIhIiQI7LgGhQ"}
    2. invoice: {document: "QTEyOEdDTQ.NCrMDyUyPxAuW_b0gEcF1BxWubdSCXEIdMVmhxt…DZZriJfjT2QdNJbjMpZh3dpguj.IBxdtmoBRUt844rZx-2ttA"}
    3. __proto__: Object

  4. gqzdqojugi4tknbv:

    1. action: {document: "QTEyOEdDTQ.EYSw4Vj-VlIEDvRB6FO3lWAyzk_bmw_97LPI18i…Kjjap6YXne1M4gXbBZ92AbJqBh.ffIV6VcHyLsgCXHQsUZyVw"}
    2. changeset: {document: "QTEyOEdDTQ.Ff44_w87BhuG5viQ2m75GF9vFpkx4Nge4xFUfxw…6F4LgcLXehjmUh7u9yjk1oo6QK.Pak2S9KU8oJBipZk5mDaJg"}
    3. conn: {document: "QTEyOEdDTQ.i7LNqEzjsvqFXlyKZLmWE0Jj-6JHSiJPuQYHCdw…kHWWuSVMYIh7Yr79iuVfwPwayA.8c6o3Ke86NdW1ldEgWoKEw"}
    4. currency_us: {document: "QTEyOEdDTQ.Np39iu7OtdlSepYuQsNqHNgCEXaWukWJZ59_4Mu…3U50h-KYB2yqq.c9H97HU6nQYf.5WWwumklVLAT6GO6sPrJQA"}
    5. invoices: {document: "QTEyOEdDTQ.1MJXW0GvMPZ4w30_-9zAw15UMJTYyqJwi3s7c33…YHQbELwTuFssGlWn0gBrvcK_io.IGOBBM2E2PTNeDfWbAzKTQ"}
    6. parent: {document: "QTEyOEdDTQ.J5hkxodrx40FchLomo7Gmdtvbhzt5nIokzYhTT0…7UZuYxQERun0fAuX7pfaqn6EFw.d0FlWlDgsNLVJgTIXZs2fg"}
    7. po_grantotal: {document: "QTEyOEdDTQ.7pdcRGyALNNERy61CMSA6KUTnlagQOxbSymK-a0…0xlk.ZtVS4b1qlgTPZakD.V2Gt.msowySouBcC2oeeqL8ZbFg"}
    8. __proto__: Object

Thanks again for the help.

grych

grych

Creator of Drab

I have no idea what can be wrong then. All looks good, the data given to form_for looks exactly the same, I have no idea where the nil may come from :frowning:

joaquinalcerro

joaquinalcerro

@grych,

So I finally identified the problem. Turns out that I use a Enum function inside the form.html.drab. This is the code:

<%= form_for @changeset, @action, fn f -> %>
  <div class="row">
    <div class="col-md-12">
      <%= render "_invoices.html", conn: @conn, invoices: @invoices, parent: @parent %>
    </div>
  </div>
.......
.......
      <div class="form-group">
        <%= label f, "Cuenta de banco", class: "control-label" %>
        <%= select f,
            :bank_account_id,
            Enum.map(assigns[:bank_accounts], &{&1.num, &1.id} ),
            class: "form-control",
            prompt: "Seleccione un número de cuenta"
         %>
        <%= error_tag f, :bank_account %>
      </div>

Please note that is use assigns[:bank_accounts] instead of @bank_accounts.

The first time this form.html.drab is rendered, this assign is there because I added it in the controller and the form renders correctly with the bank_accounts information:

  def new(conn, _params, %Epr.Debts.Contract{} = document) do
    invoices = Epr.Debts.list_unpaid_invoices(document)

      changeset =
        %PaymentOrder{}
        |> Payments.new_payment_order()

      render(
        conn,
        "new.html",
        changeset: changeset,
        parent: document,
        invoices: invoices,
        bank_accounts: Epr.Payments.list_all_bank_accounts(),
        currency_us: document.currency_us,
        po_grantotal: 0,
        type: "contract"
      )
  end

But when I check the drab assigns, it is not there:

iex(25)> socket |> assigns("form.html")
[:action, :changeset, :conn, :currency_us, :invoices, :parent, :po_grantotal]
iex(26)>

And when you poke the assign and re-render the form, the assign[:bank_accounts] is nil.

So simple solution was to change the assign[:bank_accounts] to @bank_accounts as I should and now it all works fine.

iex(29)> socket |> assigns("form.html")
[:po_grantotal, :conn, :invoices, :parent, :currency_us, :action,
 :bank_accounts, :changeset]

Thanks for your help.

Best regards,

Where Next?

Popular in Questions Top

hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a &gt; b) do {:ok, "a"} end if (a &lt; b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New

We're in Beta

About us Mission Statement