jsonelixirphoenix-frameworkelixir-poison

Poison seems to automatically convert a JSON array of objects to a map. What can I do to prevent that?


In my app I accept a JSON object at one of the API endpoints:

pipeline :api do
  plug :accepts, ["json"]
end

Within this JSON object, there is an array of objects, e.g. the structure might be like this:

{
  "a": "...",
  "b": [{"c": "...", "d": "..."}, {"c": "...", "d": "..."}]
}

In my controller, when I try to access the array of objects with params["b"], I'm surprised to find that I get a map, with the index being the original indices of the array, but in string form!

This means it's practically impossible for me to recover the original ordering of b, since the order of map traversal is not guaranteed to be preserved in Elixir.

The only thing I can do seems to be to convert the string indices back into their original integer form, and then convert the map into a list, before sorting the list, which is a lot of hassle for no apparent reason.

However, when I have a simple JSON array, e.g.

{
  "a": "...",
  "b": ["itemA", "itemB"]
}

then params["b"] in my controller indeed gives me an Elixir list, which has its order preserved and is exactly what I want.

Why did this happen? Is there anything I can do to preserve the original order of the objects in that array?


Solution

  • Turns out I wasn't sending the data correctly in the first place. the Content-Type was specified as application/x-www-form-urlencoded by default. It should be changed to application/json and the data should be JSON.stringify(data) instead. See jQuery ajax, how to send JSON instead of QueryString.