I am confused by this behavior that I'm seeing with Absinthe.
For a top-level field, e.g.
field :projects, list_of(:project) do
arg :user_id, :string
resolve(&ProjectResolver.list_projects/2)
end
If ProjectResolver.list_projects/2
returns {:ok, []}
, then the JSON result will correctly be
{
"data": {
"projects": []
}
}
However, for a subfield, e.g. the tags
field in
object :task do
field :id, :string
# ... Other fields
field :tags, list_of(:tag) do
resolve(&TaskResolver.list_tags/3)
end
# ... Other subfields
end
If TaskResolver.list_tags/3
returns {:ok, []}
, I get
{
"data": {
"task": {
"id": "ba156cde-8c5f-4806-b161-62071b0098b3",
"tags": [
null
]
}
}
}
instead of
{
"data": {
"task": {
"id": "ba156cde-8c5f-4806-b161-62071b0098b3",
"tags": []
}
}
}
which I think should be the reasonable response.
Now the non-empty array that contains one item (null
) is causing headaches for me on the frontend (apollo), and I'm not sure if there's any way I can easily work around that. It would be ideal if the data returned is an empty array in the first place, and I don't see why it's not.
Immediately after posting this question I realized that it might well be that my resolver was not returning
{:ok, []}
after all... Indeed, it was returning{:ok [nil]}
due to the Ecto query being wrong (:left_join
instead of:join
). That's why the returned JSON contains[null]
. I just needed to fix my resolver function to actually return{:ok, []}
in this case. I guess writing about an issue does help clear your thoughts on it.