Using a custom Elixir Library that uses Env variables

I created a test elixir lib that uses a file config/config.exs to store env variables for example :

config.exs :

import Config

url_dev = "DEV"
url_prod = "PROD"

config :test_lib,
  dev: [
    url: url_dev,
  ],
  production: [
    url: url_prod,
  ]

and in the lib/test_lib_elixir_package.exs, I called tha variable :

defmodule TestLibElixirPackage do
  def testFunction do
    dev_url = Application.fetch_env!(:test_lib, :dev)
    dev_url[:url]
  end
end

When I test the lib with IEX i can obtain the result of the function testFunction

But When I installed the LIB in an elixir app and tried to call the function I got this error :

“** (ArgumentError) could not fetch application environment :dev for application :test_lib because the application was not loaded nor configured
(elixir 1.13.1) lib/application.ex:683: Application.fetch_env!/2
(test_lib_elixir_package 0.1.2) lib/test_lib_elixir_package.ex:8: TestLibElixirPackage.testFunction/0”

Here is my mix.exs from the library (I included the config directory) :

defp package do
    [
      files: ["lib", "config", "mix.exs", "README*"],
      description: "Testing build and publish elixir lib",
      maintainers: ["test"],
      licenses: ["MIT"],
      links: %{}
    ]
  end

config/config.exs in library codebase is not loaded when used as a dependency.

3 Likes

Hi, But I can find it in the installed lib files :

image

I am missing something?

1 Like

It doesn’t matter if it’s there – config files of your dependencies are not used.

3 Likes

Hi LostKobrakai, So how can I make it work ?

1 Like

You can either move the values into your code or provide app env values (for your app only) via the mix.exs (see vintage_net/mix.exs at main · nerves-networking/vintage_net · GitHub)

1 Like

The idea is to provide one LIB, but the LIB provide 3 envs (dev, staging and prod) depending on the ENV of the app. How do you think it should be implemented on the LIB side ?

@LostKobrakai how this approche " or provide app env values (for your app only) via the mix.exs "

Can help me get the LIB vars ? you mean I should define the enviromnent in each app that installes the LIB ?

Ideally you should not use the application environment in libraries at all. But answering your question - yes, you should define configuration each time you use dependency.

3 Likes

To add to that, if you decide to rely on the application environment and would still like to rely on some defaults you can do something like the following:

Application.get_env(:test_lib, :dev, your: "default config")

Or a tad more readable:

@default [your: "default config"]

def some_function do
  config = Application.get_env(:test_lib, :dev, @default_config)
  # ...
end

I do something similar in my etag_plug package.

1 Like

@wolf4earth : Sorry to ask, I’m still beginner but this line will be on the LIB side ?

Application.get_env(:test_lib, :dev, your: "default config")

And this code also ?

@default [your: "default config"]

def some_function do
etc..

When we send the config from the APP to the LIB ?

Yes, that code would go into the library and then you don’t HAVE to add config :test_lib, ... into your application config.

Does that answer your question?

@wolf4earth , not really , I didn’t get the difference between :

@default [your: “default config”]

and

@default_config

Espacially the “your”

This is just an example using a module attribute (used as constant - think of JavaScript’s const). There’s no special meaning behind it.

The important part is that you can use Application.get_env/3 to set defaults and don’t NEED to set the configuration values in config/ - assuming you can provide reasonable defaults.

@wolf4earth

Here :
Application.get_env(:test_lib, :dev, @default_config)

the Library will get the env variables from where exactly (:test_lib and :dev) ? How it will fetch it besides putting values in config/ ?

I’d suggest to go through the official docs.

https://hexdocs.pm/elixir/1.12/Application.html#module-the-application-environment

And here is the documentation for Application.get_env/3:

https://hexdocs.pm/elixir/1.12/Application.html#get_env/3

1 Like

Had the same issue. In mix.exs deps part, we can change library default :prod value with :env parameter:

https://hexdocs.pm/mix/1.12/Mix.Tasks.Deps.html#module-dependency-definition-options