4
votes

I have a Phoenix/Elixir application. And I have a module in the "lib" folder in which I want to parse JSON. If it was in a controller or model, it'd be easier to do. But in the "lib" I don't have access to all those helper modules, do I? Then how can I do that? I need actually parse it in a just struct for which I don't have no model. I've looked into Poison but it seemed to that in order to use it I'd have to have a model in which I'd have to include @derive [Poison.Encoder]. Whereas I don't have one, I just want to convert a JSON string into a struct, like this:

" "\{"\"\a\": 123, "\b\": 456 "\}"\ "  ===> %{a: 123, b: 456}

How can I do that?

update

j_str = "{\"text\":\"changed readme fad996e98e04fd4a861840d92bdcbbcb1e1ec296\", \"user_name\":\"name123\"}"
Poison.Parser.parse!(~s(j_str)) # => ** (Poison.SyntaxError) Unexpected token at position 0: j

# or 
Poison.decode!(~s|j_str|) # the same error
2

2 Answers

3
votes

I need actually parse it in a just struct for which I don't have no model.

You don't need to have an Ecto model in order to use @derive [Poison.Encoder]; you can add it to plain structs as well:

defmodule AB do
  @derive [Poison.Encoder]
  defstruct [:a, :b]
end

and then do:

Poison.decode!(~s|{"a": 123, "b": 456}|, as: %AB{}) #=> %AB{a: 123, b: 456}`

From your code snippet, it looks like you may want a Map as output? You can do that by just calling Poison.decode!/1 with the string:

Poison.decode!(~s|{"a": 123, "b": 456}|) #=> %{"a": 123, "b": 456}
3
votes

You can use Poison.Parser.parse!/1 for this purpose:

iex> str = "{\"text\":\"changed readme fad996e98e04fd4a861840d92bdcbbcb1e1ec296\", \"user_name\":\"name123\"}"

iex> Poison.Parser.parse!(str)
%{"text" => "changed readme fad996e98e04fd4a861840d92bdcbbcb1e1ec296",
  "user_name" => "name123"}

Note that this will parse keys as strings, not as atoms like in your example. The reason behind this is that there is no garbage collection for atoms in Erlang/Elixir. It is possible to convert keys to atoms with Poison, but this is strongly discouraged: you might hit the max number of atoms limit in the VM, which would crash the entire VM. So the general advice is to just stick with string keys unless you know exactly what you're doing.