Circular modules: Expected {} to be a GraphQL type

Circular modules: Expected {} to be a GraphQL type


0

I came across this issue called module cycles when requiring modules.
Im working on a small star wars graphql api and ill explain in short where i got the issue :
I have two type : filmType and charecterType:

film.js:

const axios = require("axios");

const {
  GraphQLObjectType,
  GraphQLString,
  GraphQLInt,
  GraphQLList,
} = require("graphql");

const specieType = require("./specie");
const starshipType = require("./starship");
const vehicleType = require("./vehicle");
const charecterType = require("./charecter");
const planetType = require("./planet");

const getFilteredData = require("../util/loader");

module.exports = new GraphQLObjectType({
  name: "Film",
  fields: () => ({
    title: {
      type: GraphQLString,
    },
    episode_id: {
      type: GraphQLInt,
    },
    opening_crawl: {
      type: GraphQLString,
    },
    director: {
      type: GraphQLString,
    },
    producer: {
      type: GraphQLString,
    },
    release_date: {
      type: GraphQLString,
    },
    species: {
      type: new GraphQLList(specieType),
      resolve: (film, parent, args) => {
        return getFilteredData(film.species);
      },
    },
    starships: {
      type: new GraphQLList(starshipType),
      resolve: (film, parent, args) => {
        return getFilteredData(film.starships);
      },
    },
    vehicles: {
      type: new GraphQLList(vehicleType),
      resolve: (film, parent, args) => {
        return getFilteredData(film.vehicles);
      },
    },
    characters: {
      type: new GraphQLList(charecterType),
      resolve: (film, parent, args) => {
        return getFilteredData(film.characters);
      },
    },
    planets: {
      type: new GraphQLList(planetType),
      resolve: (film, parent, args) => {
        return getFilteredData(film.planets);
      },
    },
    created: {
      type: GraphQLString,
    },
    edited: {
      type: GraphQLString,
    },
  }),
});

And charecter.js:

const { GraphQLObjectType, GraphQLString, GraphQLList } = require("graphql");

const getFilteredData = require("../util/loader");

const filmType = require("./film");

module.exports = new GraphQLObjectType({
  name: "Character",
  fields: () => ({
    name: {
      type: GraphQLString,
      description: "Name of the film character",
    },
    height: {
      type: GraphQLString,
    },
    mass: {
      type: GraphQLString,
    },
    hair_color: {
      type: GraphQLString,
    },
    skin_color: {
      type: GraphQLString,
    },
    eye_color: {
      type: GraphQLString,
    },
    birth_year: {
      type: GraphQLString,
    },
    gender: {
      type: GraphQLString,
    },
    // TODO: module cycles problem
    films: {
      type: new GraphQLList(filmType),
      resolve: (character, parent, args) => {
        console.log(character);
        return [];
      },
    },
    url: {
      type: GraphQLString,
    },
    created: {
      type: GraphQLString,
    },
    edited: {
      type: GraphQLString,
    },
  }),
});

And the file that contains the rootQuery:

const axios = require("axios");
const {
  GraphQLObjectType,
  GraphQLID,
  GraphQLSchema,
  GraphQLList,
} = require("graphql");

//TODO: Search a solution on how to avoid one ugly file with all types combined!!!!
const filmType = require("./swapi-res/film");
const characterType = require("./swapi-res/charecter");

module.exports = new GraphQLObjectType({
  name: "RootQuery",
  fields: {
    film: {
      type: filmType,
      args: {
        id: { type: GraphQLID },
      },
      resolve: async (parent, args) => {
        const res = await axios.get(`https://swapi.dev/api/films/${args.id}/`);
        return res.data;
      },
    },

    films: {
      type: new GraphQLList(filmType),
      resolve: async (parent, args) => {
        const res = await axios.get("https://swapi.dev/api/films/");
        return res.data.results;
      },
    },

    character: {
      type: characterType,
      args: {
        id: {
          type: GraphQLID,
        },
      },
      resolve: async (parent, args) => {
        const res = await axios.get(`https://swapi.dev/api/people/${args.id}/`);
        return res.data;
      },
    },
  },
});

So eventually filmType type is requiring charecterType and charecterType is requiring filmType , because film can have many characters and character can play in many films.

The solutions iv looked on until now is to combine all of the types into ONE FILE

So i tried that and it seems to work, but im sure there is another way to fix this issue without making one ugly file with all the type.

How do I solve this issue ? (if more info is needed let me know)


Load 7 more related questions


Show fewer related questions

0



Leave a Reply

Your email address will not be published. Required fields are marked *