Reputation: 358
I'm new to Elixir. Currently using a Pheonix framework. I need to convert structs to list so I can use them in the select field.
In my user_controller.ex
I attempt to convert a struct to list, but the variable user_types_name
is always empty.
user_type_names = []
for user <- Accounts.list_user_types() do
user_type_names ++ [user.name]
end
While in form.html.eex
. For additional information
<%= inputs_for f, :user_type, fn cf -> %>
<%= label cf, :user_type %>
<%= select cf, :user_type, @user_type_names %>
<%= error_tag cf, :user_type %>
<% end %>
Upvotes: 0
Views: 1288
Reputation: 2212
In Elixir, for
is a construct for comprehensions. Meaning that the result will be a list built with the result of the do
clause for each element in the enumerables you use.
So, in your example, you are in fact building a list where each element is the concatenation of user_type_names
(which every time is the empty list you assigned) with the current user.name
.
What was suggested about assigning won't really work inside the for
's do
clause, because of the scoping rules. You will be reassigning it but the result will actually be the same, because it will still be the result of the match (=
).
The solution is actually far simpler than what you're doing. It's enough to do:
user_type_names = for user <- Accounts.list_user_types(), do: user.name
Upvotes: 1
Reputation: 11
You should perhaps look at Enum.map
Enum.map(1..3, fn x -> x * 2 end)
[2, 4, 6]
Enum.map returns a list by itself, so you might want do something like
user_type_names = Enum.map(Accounts.list_user_types()...)
and this should return a list.
Documentation is pretty well written : https://hexdocs.pm/elixir/Enum.html
Elixir forces you to think about what module ( Enum ) and what function ( map ) you are going to use. Think functional is the key to make things work
Upvotes: 1
Reputation: 5956
All data in Elixir is immutable. ++
is a concatenation operator, not a way to mutate a list by pushing an item onto it.
You'll need to use something like this:
user_type_names = Accounts.list_user_types()
|> Enum.map(fn(user) -> user.name end)
Or, more concisely:
user_type_names = Accounts.list_user_types()
|> Enum.map(&(&1.name))
Upvotes: 2