Edge.node field type must be Output Type but got: undefined

我只是一个虾纸丫 提交于 2019-12-23 10:58:27

问题


I'm trying to set up a node.js server with a Relay-compatible GraphQL schema.

When trying to validate or load the schema I get the following error:

EventEdge.node field type must be Output Type but got: undefined.

This is caused by having a connection type for for the Event type in one of the other type definitions.

I won't post the whole schema because it's quite verbose but when the connection field is commented out the schema is loaded correctly and no errors are thrown.

I've included an example of a simplified schema that causes the same issue:

  const graphql       = require('graphql')
  const relay         = require('graphql-relay')

  const GraphQLID         = graphql.GraphQLID,
        GraphQLInt        = graphql.GraphQLInt,
        GraphQLString     = graphql.GraphQLString,
        GraphQLList       = graphql.GraphQLList,
        GraphQLObjectType = graphql.GraphQLObjectType,
        GraphQLSchema     = graphql.GraphQLSchema,
        GraphQLNonNull    = graphql.GraphQLNonNull

  const connectionArgs               = relay.connectionArgs,
        connectionDefinitions        = relay.connectionDefinitions,
        connectionFromArray          = relay.connectionFromArray,
        cursorForObjectInConnection  = relay.cursorForObjectInConnection,
        fromGlobalId                 = relay.fromGlobalId,
        globalIdField                = relay.globalIdField,
        mutationWithClientMutationId = relay.mutationWithClientMutationId,
        nodeDefinitions              = relay.nodeDefinitions,
        toGlobalId                   = relay.toGlobalId

  // Models (ORM Mappings)
  const models = require('../models')

  // Model handlers
  const handlers = require('../models/handlers')


  /*
   *  Relay Node Definition:
   *  {nodeInterface, nodeField} = nodeDefinitions
   */

  var nodeDefinition = nodeDefinitions(
    (globalId) => {
      // {type, id} = fromGlobalId(globalId)
      const gid = fromGlobalId(globalId);

      switch (gid.type) {
      case 'User':
        return handlers.getUser(id)

      // case 'Event':
      //   return handlers.getEvent(id)
      //
      // case 'Club':
      //   return handlers.getClub(id)

      default:
        return null

      }
    },
    (obj) => {
      switch (true) {
        case (obj instanceof models.User):
          return UserType

        // case (obj instanceof models.Club):
        //   return ClubType
        //
        // case (obj instanceof models.Event):
        //   return EventType

        default:
          return null
      }
    }
  )

  /**************************
   **************************
   * Relay Connections
   *
   * { connectionType, edgeType } = connectionDefinitions({nodeType: LoremType})
   **************************
   **************************/

   // User Connection
   // const usersConnection = connectionDefinitions({name: 'User', nodeType: UserType})

   // Event Connection
   const eventsConnection = connectionDefinitions({name: 'Event', nodeType: EventType})

   // Club Connection
   // const clubsConnection = connectionDefinitions({name: 'Club', nodeType: ClubType})


   /**************************
    **************************
    * GraphQL Type Definitions
    **************************
    **************************/

    /*
    *   User Type
    *
    *   type User : Object {
    *     id: String!
    *     first_name: String
    *     last_name: String
    *     friends: [User]
    *   }
    */

   var UserType = new GraphQLObjectType({
     name: 'User',
     description: 'A user of the app.',
     fields: () => ({
       id: globalIdField('User'),
       events: {
         type: eventsConnection.connectionType,
         description: 'User\'s events.',
         args: connectionArgs,
         resolve: (user, args) => connectionFromArray(getEvents(), args)
       }
     }),
     interfaces: [nodeDefinition.nodeInterface]
   })


   /*
   **  Event Type
   *
   *   type Event : Object {
   *     id: String!
   *     title: String
   *     description: String
   *     datetime: Int
   *     location: [Int]
   *     managers: [User]
   *     club: Club
   *     members: [User]
   *   }
   */

  var EventType = new GraphQLObjectType({
    name: 'Event',
    description: 'An event in the app.',
    fields: () => ({
      id: globalIdField('Event'),
      name: {
        type: GraphQLString,
        description: 'Event\'s name.',
        resolve: event => event.get('name')
      }
    }),
    interfaces: [nodeDefinition.nodeInterface]
  })


  /****************************
   ****************************
   * Relay Mutation Definitions
   ****************************
   ****************************/


  /**************************
   **************************
   * Root Schema Definitions
   **************************
   **************************/

  /*
  **  Root Query
  *
  *   type Query {
  *     user(id: String!): User
  *     club(id: String!): Club
  *     event(id: String!): Event
  *   }
  */

  var QueryType = new GraphQLObjectType({
    name: 'Query',
    fields: () => ({
      node: nodeDefinition.nodeField,
      user: {
        type: UserType,
        resolve: () => handlers.getUser()
      }
    })
  })


  /*
  **  Root Schema
  *
  *   type Schema {
  *     query: Query
  *     mutation: Mutation
  *   }
  */

  var Schema = new GraphQLSchema({
    query: QueryType
  })


  module.exports = Schema

回答1:


You've made a reference to EventType before assigning to it. First define the type, then make use of it in the connection:

/**
 *   Event Type
 *
 *   type Event : Object {
 *     id: String!
 *     title: String
 *     description: String
 *     datetime: Int
 *     location: [Int]
 *     managers: [User]
 *     club: Club
 *     members: [User]
 *   }
 */

var EventType = new GraphQLObjectType({
  name: 'Event',
  description: 'An event in the app.',
  fields: () => ({
    id: globalIdField('Event'),
    name: {
      type: GraphQLString,
      description: 'Event\'s name.',
      resolve: event => event.get('name')
    },
  }),
  interfaces: [nodeDefinition.nodeInterface],
});

// Event Connection
const eventsConnection = connectionDefinitions({
  name: 'Event', 
  nodeType: EventType,
});


来源:https://stackoverflow.com/questions/35993661/edge-node-field-type-must-be-output-type-but-got-undefined

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!