Relay: Relay-compiler does not support union types

Created on 16 Jan 2018  路  3Comments  路  Source: facebook/relay

type HomePage {
  title: String,
  body: String,
}

type TestPage { 
  body: String,
  quote: String,
}

union Page = HomePage | TestPage;

type Query {
  pages: [Page]
}

Given the above schema i'd expect to be able to write something like this

pages {
  ... on HomePage {
    title
    body
  }
}

However i keep getting Expected undefined to be a GraphQL leaf type. anytime i include any sort of union. There have been a couple related issues that were closed without resolution:

https://github.com/facebook/relay/issues/2245
https://github.com/facebook/relay/issues/1880

Am i doing something wrong or expecting it to work in a way it wasn't meant to?

wontfix

Most helpful comment

To anyone who is having this problem, the issue isn't union types its that one or more of your union'd types is missing an id field. Relay spec requires an id field in order to use the node query, and when it comes to union types that is much more of a requirement as it has to be able to discern the type of item from the id for future queries against the same object.

To fix the issue in the example above:

type HomePage {
  title: String,
  body: String,
}

type TestPage { 
  body: String,
  quote: String,
}

union Page = HomePage | TestPage;

type Query {
  pages: [Page]
}

add ID fields

type HomePage {
  id: ID,
  title: String,
  body: String,
}

type TestPage {
  id: ID,
  body: String,
  quote: String,
}

union Page = HomePage | TestPage;

type Query {
  pages: [Page]
}

you'll also want to add a resolver for that field and use the graphql-relay library's toGlobalId method to convert numeric ids into global ids.

The way that i diagnosed this issue is by adding console.log's periodically throughout the relay-compiler bin file. Discovered that the culprit method was generateIDSelections on line 7794 of node_modules/relay-compiler/bin/relay-compiler.

then saw this comment in the file:

// Union or interface: concrete types may implement `Node` or have an `id`
// field

All 3 comments

To anyone who is having this problem, the issue isn't union types its that one or more of your union'd types is missing an id field. Relay spec requires an id field in order to use the node query, and when it comes to union types that is much more of a requirement as it has to be able to discern the type of item from the id for future queries against the same object.

To fix the issue in the example above:

type HomePage {
  title: String,
  body: String,
}

type TestPage { 
  body: String,
  quote: String,
}

union Page = HomePage | TestPage;

type Query {
  pages: [Page]
}

add ID fields

type HomePage {
  id: ID,
  title: String,
  body: String,
}

type TestPage {
  id: ID,
  body: String,
  quote: String,
}

union Page = HomePage | TestPage;

type Query {
  pages: [Page]
}

you'll also want to add a resolver for that field and use the graphql-relay library's toGlobalId method to convert numeric ids into global ids.

The way that i diagnosed this issue is by adding console.log's periodically throughout the relay-compiler bin file. Discovered that the culprit method was generateIDSelections on line 7794 of node_modules/relay-compiler/bin/relay-compiler.

then saw this comment in the file:

// Union or interface: concrete types may implement `Node` or have an `id`
// field

Instead of mysterious error compiler could explain why ID everywhere is actually a good concept https://medium.com/code-oil/relay-graphql-de-mystifying-node-id-38757121b9c

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Was this page helpful?
0 / 5 - 0 ratings