Absinthe returns an array that contains one null value instead of an empty array

546 views Asked by At

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.

1

There are 1 answers

3
xji On BEST ANSWER

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.