Search code examples
relayjs

Union types support in Relay


When you have defined field as an union of two types (in example machines contains Ships and Droid) then in Relay you can do something like that:

fragment on Faction@ relay(plural: true) {
  name,
  machines {
    ... on Ship {
      name
    }
    ... on Droid {
      name,
      primaryFunction
    }
  }
}

so under machines prop your objects are correctly evaluated, but if you want to do that using fragments from external components:

fragment on Faction@ relay(plural: true) {
  name,
  machines {
    ${StarWarsShip.getFragment('ship')}
    ${StarWarsDroid.getFragment('droid')}
  }
}

then you end up with fragment definitions under machines. It looks like you are trapped and can't check which object is which type in machines array so you can't decide which component should be used.


Solution

  • There exists a __typename field with which you should be able to introspect the type of each record:

    Query

    fragment on Faction @relay(plural: true) {
      name,
      machines {
        __typename  # <-- add this
        ${StarWarsShip.getFragment('ship')}
        ${StarWarsDroid.getFragment('droid')}
      }
    }
    

    App code

    this.props.faction.machines.map(machine =>
      machine.__typename === 'Droid'
        ? <Droid droid={machine} />
        : <Ship ship={machine} />
    );