9mm
Elixir way to conditionally update a map
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 loss how to do this without an if statement. I also don’t know if rebinding the same variable is a ‘code smell’
data = %{
requireInteraction: true,
title: title,
icon: icon,
click_action: click_action
}
if body do
data = Map.put(data, :body, body)
end
First Post!
9mm
It also warns me of this. So confusing :s
Note variables defined inside case, cond, fn, if and similar do not leak. If you want to conditionally override an existing variable “data”, you will have to explicitly return the variable. For example:
Most Liked
gregvaughn
I’ve written a helper function for this sort of thing before
def maybe_put(map, _key, nil), do: map
def maybe_put(map, key, value), do: Map.put(map, key, value)
Then you can use for multiple fields and pipe easily, for example:
data = %{
requireInteraction: true,
title: title,
icon: icon,
click_action: click_action
}
|> maybe_put(:body, body)
|> maybe_put(:other_field, other_value)
Eiji
I don’t like to have two variables with same name in scope. For me such code is less readable.
If you have only one variable like that then use if or && with || instead like:
data = %{…}
updated_data = if body, do: Map.put(data, :body, body), else: data
# or
updated_data = body && Map.put(data, :body, body) || data
In case you need to do it multiple times then I recommend to do something like:
data = %{…}
data2 = %{example: 5, body: body, sample: 10}
Enum.reduce(data2, data, fn {key, value}, acc -> value && Map.put(acc, key, value) || acc)
This is equivalent for maps:
:maps.filter(fn _key, value -> not is_nil(value) end, data)
peerreynders
Statement mindset:
Expression mindset:
Statements don’t work in an expression based language - that’s why.
Last Post!
nwjlyons
Map.merge/2 is another solution:
Map.merge(
%{
requireInteraction: true,
title: title,
icon: icon,
click_action: click_action
},
if(body, do: %{body: body}, else: %{})
)
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









