0

I am trying below code

data = Poison.decode!(payload)
    |> ProperCase.to_snake_case
Logger.info("data is #{data}")

Where the payload is from Messging Queue

    {
      "name":"Joe",
      "id": "13",
      "version": 0
    }

With this I am getting an error

[error] Could not process PerfectFlight: %Protocol.UndefinedError{description: "", protocol: String.Chars, value: %{"id" => "13", "name" => "Joe", "version" => 0}}

However, If I change my input json to

 "{
  \"name\":\"Joe\",
  \"id\": \"13\",
  \"version\": 0
}"

The Poison.decode() works pefectly fine. Now the issue is that I don't want to change my input JSON because of many reasons. What am I missing?

Edit : The code was failing not at the decode but on the next line Logger.info("data is #{data}"). Since the output of decode function is not a String I should rather use IO.inspect as below. Accepting Adams answer for his confidence in decode function.

data = Poison.decode!(payload)
    |> ProperCase.to_snake_case
IO.inspect(data)
veer7
  • 20,074
  • 9
  • 46
  • 74

1 Answers1

4

There is nothing wrong with Poison:

iex(1)> Poison.decode!(~S'{"name":"Joe", "id": "13", "version": 0}')
%{"id" => "13", "name" => "Joe", "version" => 0}

Your example also works for me:

iex(1)> payload = ~S'{"name":"Joe", "id": "13", "version": 0}'
"{\"name\":\"Joe\", \"id\": \"13\", \"version\": 0}"
iex(2)> Poison.decode!(payload) |> ProperCase.to_snake_case
%{"id" => "13", "name" => "Joe", "version" => 0}

The error you are getting is probably because something somewhere is trying to convert a map to a string:

iex(1)> IO.puts %{"id" => "13", "name" => "Joe", "version" => 0}
** (Protocol.UndefinedError) protocol String.Chars not implemented for %{"id" => "13", "name" => "Joe", "version" => 0}

It looks like you're getting an error while trying to debug your problem. You could use IO.inspect instead of IO.puts for debugging, and see if you can get a more helpful error message.

Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
  • The difference in those additional single quotes. Here is what I was trying `Poison.decode!({"name":"Joe", "id": "13", "version": 0})`. This is how the message comes as a `payload` from `Messaging Queue`. – veer7 Oct 23 '18 at 07:54
  • @veer7 that's not possible, because JSON is not valid elixir syntax. You would have got `SyntaxError`, not a `Protocol.UndefinedError`. – Adam Millerchip Oct 23 '18 at 08:01
  • 1
    I'm getting you quoted the JSON, then got the error trying to log the successfully parsed resulting map with `IO.puts`. – Adam Millerchip Oct 23 '18 at 08:07
  • Correct! It's a syntax error with `Poison.decode!({"name":"Joe", "id": "13", "version": 0})`. – veer7 Oct 23 '18 at 08:37