9mm

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

Most Liked

gregvaughn

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

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

peerreynders

Statement mindset:

Expression mindset:

Statements don’t work in an expression based language - that’s why.

WolfDan

WolfDan

Imo this is a elixir way as well to do it:

data = %{
  requireInteraction: true,
  title: title,
  icon: icon,
  click_action: click_action
}

data =
    if body do
      Map.put(data, :body, body)
    else
      data
    end

personally I’d prefer to create more functions like MrDoops pointed out, you can do anonymous functions as well

MrDoops

MrDoops

You can use Map.has_key?(data, :body) with a case statement. A more Elixir way might be to pattern match on the presence or absence of the map.

def process(%{body: _} = data), do: data
def process(%{} = data), do: %{data | body: nil}

Where Next?

Popular in Questions Top

vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
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
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
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
wernerlaude
In AR this is so simple @articles = current_user.articles How to do in Ecto? def index(conn, _params) do current_user = conn.assig...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
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

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3268 119930 1237
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30048 115
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
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
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
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
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New

We're in Beta

About us Mission Statement