Skip to content Skip to sidebar Skip to footer

GraphQL: One Of The Provided Types For Building The Schema Is Missing A Name

I'm learning GraphQL so I got a strange issue I have this code on one file Schema.js: const graphQL = require('graphql'); const lodash = require('lodash') const { GraphQLObjectType

Solution 1:

You are facing a problem in the way nodeJs handle require. See http://nodejs.org/api/modules.html#modules_cycles for how require is handled in node.

Specifically in your case, when you do:

const StatusType = require('./StatusType');
const UserType = require('./UserType');
  1. StatusType is loaded from const StatusType = require('./StatusType');
  2. StatusType.js loads UserType from const UserType = require('./UserType')
  3. UserType.js should require StatusType but nodeJs prevent this to avoid infinite loop. As a result, it executes next lines
  4. UserType is initialized as new GraphQLObjectType(...) and defined fields as a function. The function closure hand a variable StatusType not yet initialized. It's just an empty exported module {}

You can verify that adding console.log(StatusType); when creating UserType fields:

const UserType = new GraphQLObjectType({
  name: 'User',
  fields: () => {
    console.log(StatusType);
    return ({
      id: { type: GraphQLString },
      username: { type: GraphQLString },
      mail: { type: GraphQLString },
      password: { type: GraphQLString },
      status: {
        type: StatusType,
        resolve(parentValue, args) {

        }
      },
    });
  }
});

You'll get:

{} //instead of StatusType

You didn't encounter this problem when everything was in the same file because both UserType and StatusType are defined within the same closure and now each others.

To resolve that you had to define UserType and StatusType on the same level and inject them. A good example of how to do it can be found here. In your case:

// StatusType.js
const StatusType = (types) => new GraphQLObjectType({
  name: 'Status',
  fields: () => {
    console.log(types.UserType);
    return ({
      id: { type: GraphQLInt },
      statusName: { type: GraphQLString },
      user: {
        type: new GraphQLList(types.UserType),
        resolve(parentValue, args) {

        }
      }
    });
  }
});

module.exports = StatusType;

// UserType.js
const UserType = (types) => new GraphQLObjectType({
  name: 'User',
  fields: () => {
    console.log(types.StatusType);
    return ({
      id: { type: GraphQLString },
      username: { type: GraphQLString },
      mail: { type: GraphQLString },
      password: { type: GraphQLString },
      status: {
        type: types.StatusType,
        resolve(parentValue, args) {

        }
      },
    });
  }
});
module.exports = UserType;

// Schema.js
const StatusTypeInject = require('./StatusType');
const UserTypeInject = require('./UserType');

const types = {};
types.StatusType = StatusTypeInject(types);
types.UserType = UserTypeInject(types);

const StatusType = types.StatusType;
const UserType = types.UserType;


Solution 2:

You could do with some cleaning up here and here's how I'd resolve these situations:

[..]
// import GraphQLNonNull from the graphql lib
// In your case, I'd use GraphQLID instead of GraphQLString

userSome: {
  type: new GraphQLList(require('../path/to/UserType')),
  args: { id: { type: new GraphQLNonNull(GraphQLID) } },
  resolve: async (parentValue, args) => {
    // No need for the if statement as we'd sure to have an id.
    // return await filter users by id.
  }
},
[..]

And as always, keep your fields as functions: fields: () => ({})


Solution 3:

You are importing UserType inside StatusType before declaration.

const StatusType = require('./StatusType');
const UserType = require('./UserType');

Post a Comment for "GraphQL: One Of The Provided Types For Building The Schema Is Missing A Name"