graphqlelixirabsinthe

Absinthe union type resolver providing an empty map to object field resolver


I'm trying to implement a GraphQL union type in Absinthe.

We have two objects, :foo and :bar and a union type :info that resolves to one of those types.

object :contact do
  field :info, list_of(:info)
end

object :foo do
  field :phone, non_null(:string),
    resolve: fn foo, _ ->
      IO.inspect(foo) # <-- is %{}
      {:ok, "hardcodedfornow"}
    end
end

object :bar do
  field :id, non_null(:string),
    resolve: fn id, _b ->
      IO.inspect(id) # <-- is %{}
      {:ok, "hardcodedfornow"}
    end
end

union :info do
  description("")

  types([:foo, :bar])

  resolve_type(fn
    %{"info" => "foo"}, _ ->
      :foo

    %{"info" => "bar"}, _ ->
      :bar
  end)
end

For some reason, each custom resolver is receiving an empty map %{} as its first argument.

When resolving the type, we do have a map with an "info" field (as well as more fields).

Why are the custom resolvers not receiving the same map that the union type resolver receives?


Solution

  • The issue was that I wasn't resolving the object's field properly.

    This is correct:

    object :foo do
      field :phone, non_null(:string) do
        resolve(fn foo, _, _ ->
          {:ok, foo["phone"]}
        end)
      end
    end
    

    This is incorrect:

    object :foo do
      field :phone, non_null(:string),
        resolve: fn foo, _ ->
          {:ok, foo["phone"]}
        end
    end