I'm currently using Dayron to interact with a jsonapi.org spec API (and it's working great! ๐), but ran into an issue deserializing the data. The JSON-API spec returns either a top level data
key or a top-level errors
keys. This runs into an issue with Dayron because in Dayron.Model
the first method that gets called is __from_json_list__/2
(
|
def __from_json_list__(data, opts) when is_list(data) do |
) which assumes the array of results is at the root level.
So, when JSON-API returns an array of records nested inside of the data
attribute, Dayron sees there is no list at the root level, then it tries to apply the attributes to a struct, which results in an empty struct being returned.
I was able to correct his behavior by mapping the data key instead:
def __from_json_list__(%{data: data}, opts) do
Enum.map(data, &__from_json__(&1, opts))
end
This also had the benefit of allowing me to match on the error key as well:
def __from_json_list__(%{errors: errors}, opts) do
# ...
end
But this is not currently allowed by the Dayron library. I had to adjust the Dayron.Model
to allow the __from_json_list/2` to be overridable, otherwise the library models took precedence:
# lib/dayron/model.ex#96
defoverridable [__url_for__: 1, __from_json__: 2, __from_json_list__: 2]
With the overridable change to the library and the custom __from_json_list__/2
method on the model, I was able to achieve the desired result.