I am new to Elixir/Phoenix and trying to learn by building a small app.
I am fetching data from a 3rd party API and keep getting the following error.
(ArgumentError) argument error :erlang.iolist_to_binary([%{"24h_volume" => "1000", "name" => "some_name"},{...}])
What I have in my controller is:
HTTPoison.start
%HTTPoison.Response{body: body} = HTTPoison.get!(url)
body = body
|> Poison.decode!(keys: :atoms!)
This does not work. I have used (keys: :atoms) which is discouraged in the Poison documentation.
Here is my schema:
schema "things" do
field :name, :string
field :volume_24h, :float
timestamps()
end
@doc false
def changeset(%Thing{} = thing, attrs) do
thing
|> cast(attrs, [:volume_24h, :name])
|> validate_not_nil([:volume_24h, :name])
end
def validate_not_nil(changeset, fields) do
Enum.reduce(fields, changeset, fn field, changeset ->
if get_field(changeset, field) == nil do
add_error(changeset, field, "nil")
else
changeset
end
end)
end
I am trying to use a different field name for "24h_volume" and I get this error:
(ArgumentError) argument error :erlang.binary_to_existing_atom("24h_volume", :utf8)
I am clearly missing something here.
Is there a way to pass the desired field name to Poison because "24h_volume" will not be a valid atom? How can I fix these errors?
You have a mess with volume_24h
parameter.
As it is stated in Poison
documentation:
Note that
keys: :atoms!
reuses existing atoms, i.e. if:name
was not allocated before the call, you will encounter an argument error message.
This is exactly what happens. The application expects the :volume_24h
key to come from the request, but it (for some reason, possibly due to a form misconfiguration of like) receives 24h_volume
. By using the permissive atoms
call instead of atoms!
you did not solve anything, you have the issue hidden. What actually happens, 24h_volume
key comes and is being effectively discarded by the call to cast
.
What you need is either to fix the fronend/request sender to send volume_24h
key, or to fix the controller to accept :"24h_volume"
key.
There are two reasons behind discouraging atoms
usage. The one is described in the Poison
documentation: so called “atoms DOS attack” is possible with the random requests having random keys being issued subsequently, overflowing the atom storage. The second is that by using banged version atoms!
one protects themselves from typos/misconfiguration like the one above.
FWIW, the atom for the proper key is being allocated in schema definition.