Meaning of "Expected undefined to be a GraphQL type"?

709 Views Asked by At

I am setting up my first GraphQL endpoint with graphql and graphql-express. My MongoDB schema has two types: User and Card, where a User can have many Cards. I set up the root types and resolvers with no issues. I can query and mutate users and cards in the database.

My problem comes when I try to nest cards in users, and I get Error: Expected undefined to be a GraphQL type. The error only appears when I set UserType.fields.cards.type to be an instance of graphql.GraphQLList, yet I had an identical field value in QueryType.js, and that works fine.

Looking at other questions on Stack Overflow, it appears that my problem could be a cyclical reference between my User and Card types, but I am struggling to find any problems in my code. Is there something I'm missing here?

The full stack trace is:

Error: Expected undefined to be a GraphQL type.
    at assertType (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/definition.js:97:11)
    at new GraphQLList (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/definition.js:323:19)
    at GraphQLList (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/definition.js:325:12)
    at fields (/Users/QuestionMark/Documents/flash-cards/server/schema/types/UserType.js:16:13)
    at resolveThunk (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/definition.js:480:40)
    at defineFieldMap (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/definition.js:692:18)
    at GraphQLObjectType.getFields (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/definition.js:633:27)
    at collectReferencedTypes (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/schema.js:366:81)
    at collectReferencedTypes (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/schema.js:368:9)
    at new GraphQLSchema (/Users/QuestionMark/Documents/flash-cards/node_modules/graphql/type/schema.js:153:7)
    at Object.<anonymous> (/Users/QuestionMark/Documents/flash-cards/server/schema/schema.js:5:16)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)

Here is my relevant code for reference:

// ./UserType.js
const {
  GraphQLObjectType, GraphQLList, GraphQLID, GraphQLString
} = require('graphql');
const { CardType } = require('./CardType');
const { cardsResolver } = require('../resolvers/userResolvers');

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => ({
    _id: { type: GraphQLID },
    username: { type: GraphQLString },
    password: { type: GraphQLString },
    firstname: { type: GraphQLString },
    lastname: { type: GraphQLString },
    cards: {
      type: GraphQLList(CardType),
      resolve: cardsResolver
    }
  })
});

module.exports = UserType;

// ./CardType.js
const { GraphQLObjectType, GraphQLID, GraphQLString } = require('graphql');

const CardType = new GraphQLObjectType({
  name: 'Card',
  fields: {
    _id: { type: GraphQLID },
    title: { type: GraphQLString },
    body: { type: GraphQLString },
    group: { type: GraphQLString }
  }
});

module.exports = CardType;

// ./root/QueryType
const {
  GraphQLObjectType,
  GraphQLList,
  GraphQLID,
  GraphQLString
} = require('graphql');
const UserType = require('../UserType');
const CardType = require('../CardType');
const {
  userResolver,
  usersResolver,
  cardResolver,
  cardsResolver
} = require('../../resolvers/root/queryResolvers');

const QueryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    user: {
      type: UserType,
      args: {
        _id: { type: GraphQLID },
        username: { type: GraphQLString }
      },
      resolve: userResolver
    },
    users: {
      type: GraphQLList(UserType),
      resolve: usersResolver
    },
    card: {
      type: CardType,
      args: {
        _id: { type: GraphQLID }
      },
      resolve: cardResolver
    },
    cards: {
      type: GraphQLList(CardType),
      resolve: cardsResolver
    }
  }
});

module.exports = QueryType;

1

There are 1 best solutions below

0
On BEST ANSWER

In UserType.js, I destructured the output of require('./CardType') which resulted in CardType being undefined. GraphQLList expected an instance of GraphQLObjectType but instead received undefined, hence the error.

    const { CardType } = require('./CardType'); // old code
    const CardType = require('./CardType'); // new code