Search code examples
javascriptgraphqlgraphql-js

GraphqlJS- Type conflict- Cannot use union or interface


const {
  makeExecutableSchema
} = require('graphql-tools');
const resolvers = require('./resolvers');

const typeDefs = `

  type Link {
    args: [Custom]
  }

  union Custom = One | Two

  type One {
    first: String
    second: String
  }

  type Two {
    first: String
    second: [String]

  }

  type Query {
    allLinks: [Link]!

  }

`;

const ResolverMap = {
  Query: {
    __resolveType(Object, info) {
      console.log(Object);
      if (Object.ofType === 'One') {
        return 'One'
      }

      if (Object.ofType === 'Two') {
        return 'Two'
      }
      return null;
    }
  },
};

// Generate the schema object from your types definition.
module.exports = makeExecutableSchema({
  typeDefs,
  resolvers,
  ResolverMap
});


//~~~~~resolver.js
const links = [
    {
        "args": [
            {
                "first": "description",
                "second": "<p>Some description here</p>"
            },
            {
                "first": "category_id",
                "second": [
                    "2",
                    "3",
                ]
            }

        ]
    }
];
module.exports = {
    Query: {
        //set data to Query
        allLinks: () => links,
        },
};

I'm confused because the documentary of graphql is so bad. I don't know how to propertly set resolveMap function to be able to use union or interface in schema. For now when I'm using query execution it shows me error that my generated schema cannot use Interface or Union types for execution. How can I execute properly this schema?


Solution

  • resolvers and ResolverMap should be defined together as resolvers. Also, type resolver should be defined for the Custom union type and not for Query.

    const resolvers = {
      Query: {
        //set data to Query
        allLinks: () => links,
      },
      Custom: {
        __resolveType(Object, info) {
          console.log(Object);
          if (Object.ofType === 'One') {
            return 'One'
          }
    
          if (Object.ofType === 'Two') {
            return 'Two'
          }
          return null;
        }
      },
    };
    
    // Generate the schema object from your types definition.
    const schema = makeExecutableSchema({
      typeDefs,
      resolvers
    });
    

    Update: OP was getting an error "Abstract type Custom must resolve to an Object type at runtime for field Link.args with value \"[object Object]\", received \"null\".". It’s because the conditions in type resolver Object.ofType === 'One' and Object.ofType === 'Two' are always false as there is no field called ofType inside Object. So the resolved type is always null.

    To fix that, either add ofType field to each item in args array (links constant in resolvers.js) or change the conditions to something like typeof Object.second === 'string' and Array.isArray(Object.second)