System.put_env with deep merge or something like that

Hello,

I’m trying to update (in runtime with System.put_env) one specific system/config property inside a group of properties. For example in my “config.ex” file I have something like that:


config :my_app, :group,
pp_1: “example_1”,
pp_2: “example_2”

In runtime I’m trying update pp_2 without change pp_1 value and for that I’m trying with:

1)System.put_env(:my_app, :group[:pp_2], “abc123”)
2)System.put_env([:my_app, :group], :pp_2, “abc123”)
3)System.put_env(:my_app, :group, %{pp_2: “abc123”})

System.get_env(:my_app, :group)

Returns:
%{
pp_2: “abc123”
}

But this is wrong!!

How do I make update of only one property in a group?

I think you’re looking for Application.put_env/4 (and its siblings), not System.put_env/2.

1 Like

Something like:

new_config = 
  :my_app
  |> Application.get_env
  |> put_in([:group, :pp_2], "abc123"]

Application.put_env(:my_app, new_config)

Would be my suggestion.

1 Like

I have that solution implemented but need get_all properties in a group when I just want set one value inside a group.

Now I use something like that but why I need get all env inside group?

Thanks for trying help!

You are right (sorry my mistake) … but my main question is different.
See follow example please

Thanks for trying help!

Happy to help but I don’t know at this point what the question is?

I want update value without replace the other values (without Application.get_env)… just with Application.put_env call. It’s possible?

I think there’s an important bit of understanding required application the structure of the application environment. Under the covers, the environment for each application is a keyword list. Using your example:

iex> Application.get_all_env :my_app
[group: [pp_1: "example_1", pp_2: "example_2"]]

Here you can see that for your app :my_app there is one configuration key, :group which has the value [pp_1: "example_1", pp_2: "example_2"]. Application.get_env/3 is very similar to:

:my_app
|> Application.get_all_env
|> Keyword.get(:group)

for your example.

This is reason why, when you want to update the value for :group, you need to replace the whole value for :group since thats the configuration key. And being an immutable language you can just mutate the exisiting value.