Graphql-js: Unable to make cross links between types

Created on 5 Jul 2015  路  6Comments  路  Source: graphql/graphql-js

Vectors in graph could reference to each other in any direction.
So I should be able to use GraphQL type before it's implementation.
I don't found a possibility to do this right now. Am I right?

Most helpful comment

GraphQL types can refer to themselves by implementing fields as a function rather than an object. In fact, supplying an object is a shorthand for a function that returns that object:

var RecursiveType = new GraphQLObjectType({
  name: 'Recursive',
  fields: {
    recurse: { type: RecursiveType }
  }
});

Will not work because you reference RecursiveType before it's defined. Instead, use a function for fields.

var RecursiveType = new GraphQLObjectType({
  name: 'Recursive',
  fields: function () {
    return {
      recurse: { type: RecursiveType }
    }
  }
});

Or if you're using ES6 arrow functions

var RecursiveType = new GraphQLObjectType({
  name: 'Recursive',
  fields: () => ({
    recurse: { type: RecursiveType }
  })
});

The function is called after the type is defined, ensuring the variable has been set before it is referenced.

All 6 comments

Also GraphQL type could reference to itself.

GraphQL types can refer to themselves by implementing fields as a function rather than an object. In fact, supplying an object is a shorthand for a function that returns that object:

var RecursiveType = new GraphQLObjectType({
  name: 'Recursive',
  fields: {
    recurse: { type: RecursiveType }
  }
});

Will not work because you reference RecursiveType before it's defined. Instead, use a function for fields.

var RecursiveType = new GraphQLObjectType({
  name: 'Recursive',
  fields: function () {
    return {
      recurse: { type: RecursiveType }
    }
  }
});

Or if you're using ES6 arrow functions

var RecursiveType = new GraphQLObjectType({
  name: 'Recursive',
  fields: () => ({
    recurse: { type: RecursiveType }
  })
});

The function is called after the type is defined, ensuring the variable has been set before it is referenced.

@leebyron Thank you very much for quick reply!

@leebyron Very helpfull, thanks!
That happened to me when I include same GraphQLObjectType in different files. But I have also Enum dependent in different files
Do you know how to make same trick with GraphQLEnumType?

@leebyron

Thanks for the tips here.

What if I'm declaring a GraphQLUnionType instead of GraphQLObjectType?

I have a NestedType with a 'parent' attribute that is defined as a UnionParentType.

const UnionParentType = GraphQLUnionType({
  name: 'ParentType',
  types: [RootType, NestedType],
  resolveType: (parent) => {
    if (parent instanceof Root) {
      return RootType;
    }
    return NestedType;
  }
});

When I run this - It doesn't work.
I get an error Error: ParentType may only contain Object types, it cannot contain: undefined.

Is it possible to work recursively like this with union types?

Is it possible to work recursively like this with union types?

The types property of a GraphQLUnionType can also be thunk, so the previous error might be fixed with:

const UnionParentType = GraphQLUnionType({
  name: 'ParentType',
  types: () => [RootType, NestedType], // <--- this changed
  resolveType: (parent) => {
    if (parent instanceof Root) {
      return RootType;
    }
    return NestedType;
  }
});

I was also getting an error like:

Type may only contain Object types, it cannot contain: undefined

It was fixed by changing types from an array to a function that returns an array.

Was this page helpful?
0 / 5 - 0 ratings