ab = %{a: 1}
ac = %{"a" => 1}
What exactly is the difference? And why does Poison.decode! return format #2 (I need #1 to use with Ecto.Changeset.change).
Json response is taken from API and looks like
[{"a":3}]
ab = %{a: 1}
ac = %{"a" => 1}
What exactly is the difference? And why does Poison.decode! return format #2 (I need #1 to use with Ecto.Changeset.change).
Json response is taken from API and looks like
[{"a":3}]
ab = %{a: 1} # atom key you can access it like ab.a
ac = %{"a" => 1} # string key you can access it ac["a"]
Poison.decode! return format #2:
Data which comes from outside your application, broadly speaking, can’t be trusted. Given that atom allocation can lead to memory exhaustion in a long-running Erlang system, using atoms for external data opens up your app for a potential denial of service (DoS) attack.
This fact is reflected in many Elixir libraries, for example the popular JSON parser Poison. Well-behaved libraries will generally use strings as map keys when converting external data into an internal data structure
If you want to convert map keys from string to atom.You can do:
iex> maps = %{"foo" => "bar"}
%{"foo" => "bar"}
iex> for {key, val} <- maps, into: %{}, do: {String.to_atom(key), val}
%{foo: "bar"}
ab.a
in the example, can also be done with ab[:a]
. The bracket syntax is the more general access syntax, while the dot syntax is sugar available for maps and structs, when the key is an atom. –
Theogony © 2022 - 2024 — McMap. All rights reserved.
String.to_existing_atom/1
, to be a bit safer. UsingString.to_atom/1
would open up exactly the vulnerability mentioned in this answer. – Theogony