als9xd
als9xd

Reputation: 854

__resolveType returning empty objects

I'm trying to implement form validation using graphql. For some reason when I run this query:

mutation validateForm($input: ValidateFormInput!) {
    test: validateForm(
       input: $input
    ) {
        id
        fieldValidations {
            ... on FailedValidation {
                id
            }
        }
    }
  }

and there is one field validation with not errors('SuccessfullValidation') it returns {id:'some-id',fieldValidations:[{}]} when it should be returning {id:'some-id',fieldValidations:[]}. This especially doesn't make any sense to me because ID is marked as non nullable field in both fields however I don't receive any errors.

Resolvers

FieldValidation: {
    __resolveType(obj: any) {
        if (obj.error || (obj._doc && obj._doc.error)) {
            return 'FailedValidation';
        }
        return 'SuccessfullValidation';
    },
}

Type definitions

type SuccessfullValidation {
    id: ID!

    filter: Filter!
    field: Field!
}

type TestError {
    hint: String!
    details: String!
}

type FailedValidation {
    id: ID!

    filter: Filter!
    field: Field!
    error: TestError
}

union FieldValidation = SuccessfullValidation | FailedValidation

extend type Query {
    getFieldValidations: [FieldValidation!]!
}

type FormValidation {
    id: ID!
    fieldValidations: [FieldValidation!]!
}

input ValidateFormInputFields {
    id: String!
    value: String! 
}

input ValidateFormInput {
    fields: [ValidateFormInputFields!]!
    userId: Int!
}


extend type Mutation {
    validateForm(input: ValidateFormInput!): FormValidation!
}

Upvotes: 1

Views: 705

Answers (1)

Daniel Rearden
Daniel Rearden

Reputation: 84687

This is expected behavior. From the spec:

Fragments can be defined inline within a selection set. This is done to conditionally include fields based on their runtime type.

Type conditions (i.e. on FailedValidation) are just a way to filter what fields are resolved based on the runtime type. They are not a way to filter the actual list of results -- there is no built-in filtering in GraphQL.

If you want to filter the list of FieldValidations returned by the fieldValidations, you'll need to add some kind of argument to the field and then implement the appropriate resolver logic.

As an aside, you won't see a validation error for a non-null field being null unless that field is actually requested and it resolves to null. In this case, your type condition on the inline fragment resulted in effectively an empty selection set -- from GraphQL's perspective, the id field was not requested, and so it doesn't do a null check for it.

Upvotes: 1

Related Questions