I need to process optional params (from post body) to send them in request, my actual implementation :
body =
if params["book_name"] do
%{
book_price: book_price,
book_name: params["book_name"]
}
else
%{
book_price: book_price
}
end
with {:ok, result} <- post_book(body, opts) do
{:ok, result}
else
{:error, error} -> {:error, error}
end
defmodule Example do
# function specification
@spec sample(params :: map(), body :: map(), optional_params :: list(atom())) :: map()
# optional param values, so you can call
# Example.sample(params)
def sample(params, body \\ %{}, optional_params \\ [])
# function guards
when is_map(params) and is_map(body) and is_list(optional_params) do
# list of atoms
optional_params
# map with atom keys and string values
|> Map.new(&{&1, Atom.to_string(&1)})
# reduce optional params over base/generic body
|> Enum.reduce(body, fn
# when params have optional params (string key)
{atom_param, string_param}, acc when is_map_key(params, string_param) ->
# put to accumulator (body) value from params (string key) under atom key
Map.put(acc, atom_param, params[string_param])
# in any other case i.e. when said optional param does not exists in params
_optional_param, acc ->
# simply return our accumulator
acc
end)
end
end
# some data
book_price = 10
base_body = %{book_price: book_price}
optional_params = ~w[book_name]a
# empty params
body = Example.sample(%{}, base_body, optional_params)
# non empty params
body = Example.sample(%{"book_name" => "Sample"}, base_body, optional_params)
Also in this part:
with {:ok, result} <- post_book(body, opts) do
{:ok, result}
else
{:error, error} -> {:error, error}
end
with is useless, because you always return post_body/2 output anyway.