Is there an option to add a default fallback value in get_in/2?
Scenario:
merge_maps = get_in(
payload, ["msg", "clicks"]
) ++ get_in(
payload, ["msg", "opens"]
)
if the key "clicks" or "opens" isn't found in the nested "msg" map, get_in/2 will return nil which then thrown an error:
** (ArgumentError) argument error
:erlang.++(nil, nil)
(stdlib) erl_eval.erl:670: :erl_eval.do_apply/6
(iex) lib/iex/evaluator.ex:250: IEx.Evaluator.handle_eval/5
(iex) lib/iex/evaluator.ex:230: IEx.Evaluator.do_eval/3
(iex) lib/iex/evaluator.ex:208: IEx.Evaluator.eval/3
(iex) lib/iex/evaluator.ex:94: IEx.Evaluator.loop/1
(iex) lib/iex/evaluator.ex:24: IEx.Evaluator.init/4
Would be nice to be able to do something like
get_in(payload, ["msg", "clicks"], [])
where the empty list would be the fallback value if no value with that key is found. What's the right way to achieve this?
Update
Thanks to the answer from @PatNowak I implemented a wrapper around get_in:
defmodule Helpers.AccessHelper do
def get_in_attempt(data, keys, default \\ []) do
case get_in(data, keys) do
nil -> default
result -> result
end
end
end
And then in another file:
import Helpers.AccessHelper, only: [get_in_attempt: 2]
merge_maps = get_in_attempt(
payload, ["msg", "clicks"]
) ++ get_in_attempt(
payload, ["msg", "opens"]
)
You can write your own wrapper for Kernel.get_in/2, but with using default value as a fallback.
def get_in_attempt(data, keys, default) do
case get_in(data, keys) do
nil-> default
result -> result
end
end
so in your case it's enough to have
def get_in_attempt(data, keys) do
case get_in(data, keys) do
nil-> [] # your default is set, so don't need to pass it
result -> result
end
end
However, using first approach (with explicit default argument is more flexible and can be reused in different scenarios).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With