fireproofsocks

fireproofsocks

Complex loop in EEx

I’m trying to build a loop in an EEx template that may have to iterate over a list OR a map (i.e. loop over its keys/values) and include an index (yes, I know that’s a lot).

So far, my EEx template looks like this:

The start...
<%= Enum.with_index(list)
|> Enum.map(fn {x, index} ->
    case x do
      {k, v} -> %>
        <%= k %> <%= v %>: @index: <%= index %>
    <% x -> %>
          <%= x %>: @index: <%= index %>
    <% end %>
<% end) %>
...The end.

But that results in an error:

** (TokenMissingError) nofile:12: missing terminator: end (for "fn" starting at line 3)
    lib/eex/compiler.ex:101: EEx.Compiler.generate_buffer/4
    lib/eex/compiler.ex:54: EEx.Compiler.generate_buffer/4
    lib/eex.ex:199: EEx.eval_string/3
    my_file.exs:37: (file)

A simpler EEx template works:

The start...
<%= Enum.with_index(list)
|> Enum.map(fn {x, index} -> %>
      <%= x %>: @index: <%= index %>
<% end) %>
...The end.

but that one only handles lists. I think I’m getting stuck on where exactly I’m allowed to break in and out of Elixir code within an EEx template. The basic logic works when it’s not in EEx.

Thanks for any pointers!

Most Liked

patrickdm

patrickdm

Hello, I’d try to simplify it by moving the function to the view module, using string interpolation, i.e. (disclaimer: untested code ahead…)

def eval_item(x, index) do
  case x do
    {k, v} -> 
      "#{k} #{v} : @index: #{index}"
    val ->
      "#{val} : @index: #{index}"
    end
end

or with two functions using pattern matching on arguments (that I prefer as I find it easier to read):

def eval_item({k, v} = x, index), do: "#{k} #{v} : @index: #{index}"

def eval_item(x, index), do: "#{x} : @index: #{index}"

then in the template you could just:

<%= Enum.with_index(list) |> Enum.map(&eval_item/2) %> 

hth.

kokolegorille

kokolegorille

I would even go further and put all logic in a helper function. Putting logic in the template is not something I would advise.

Somehing like

<%= do_something(list) %> 
patrickdm

patrickdm

yes, good advice! :slight_smile:

[…edit…] Putting all together would look like:

in template.html.eex

<%= iterate_over(list) %> 

in template_view.ex

def iterate_over(list) do
 list
 |> Enum.with_index()
 |> Enum.map(&eval_item/2)
end

defp eval_item({k, v} = _x, index), do: "#{k} #{v} : @index: #{index}"

defp eval_item(x, index), do: "#{x} : @index: #{index}"
Ninigi

Ninigi

<% %> doesn’t work like that (been there tried that :slight_smile:), and you can simplify the map/case by pattern matching in the function signatures.

untested:

<%= Enum.with_index(list) |> Enum.map(fn
  {{k, v}, index} ->
    "#{k} #{v}: @index: #{index}"
  {x, index} ->
    "#{x}: @index: #{index}"
end) %>

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
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
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

Other popular topics Top

lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
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

We're in Beta

About us Mission Statement