Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional default value for get_in Access behavior elixir

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"]
)
like image 814
Cyzanfar Avatar asked Nov 01 '25 13:11

Cyzanfar


1 Answers

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).

like image 153
PatNowak Avatar answered Nov 04 '25 10:11

PatNowak