23
votes

I've got an issue on my project and I can't find any solution on the internet. Here is the situation.

  • I've an Union (DataResult) of 2 types (Teaser & Program)
  • I've a Zone type with a data field (an array DataResult)
  • Teaser & Program have the same title field with a different type (String vs String!)

Here is parts from Zone, Teaser and Program schemas:

type Program {
    title: String
}

type Teaser {
    title: String!
}

union DataResult = Teaser | Program

type Zone {
    (...)
    data: [DataResult!]
}

When I tried to query zone data as described in the query part below, I've got an error from GraphQL.

zones {
    ...zoneFieldsWithoutData
    data {
        ... on Program {
            ...programFields
        }
        ... on Teaser {
            ...teaserFields
        }
    }
}

Here is the error:

Error: GraphQL error: Fields \"title\" conflict because they return conflicting types String and String!. Use different aliases on the fields to fetch both if this was intentional

I can't use an alias because the specs needs the same attribute name for all "DataResult" entities. What can I do ?

Moreover, even if I set the same Type for title, I've a lot of warning about "missing fields" in the console....

PS: I use Vanilla Apollo as GraphQL client (on the server side)

3
I believe this is related to github.com/graphql/graphql-js/issues/53 and github.com/facebook/graphql/pull/120 - as long as concrete type is known, fields with the same name shouldn't collide.Jiří Brabec
Looking at it from a plain JS objects point, you are expecting something like { data { title: 'Title 1', title: 'Title 2' }} which doesn't make a lot of sense since you might not differentiate between what title belongs to Program or Teaser and that's why it insists on using aliases.kimobrian254

3 Answers

1
votes

Using an interface solved this problem for me, including the "missing field" - errors (although this means the fields have to be of the same type I think).

Something along the lines of

interface DataResult {
    title: String!
}

type Program implements DataResult {
    // Not sure if this can be empty?
}

type Teaser implements DataResult {
    // Not sure if this can be empty?
}

type Zone {
    (...)
    data: [DataResult!]
}
0
votes

I know that you cannot use an alias, but for everyone else who can (including me):

The simple answer taken from github is to use field aliases:

zones {
    ... on Program {
        programTitle: title
    }
    ... on Teaser {
        teaserTitle: title
    }
}