0

I just started to learn GraphQL and did a simple example. I have this schema

const {
    GraphQLObjectType,
    GraphQLString,
    GraphQLSchema,
    GraphQLID,
    // GraphQLInt,
    GraphQLList,
    GraphQLNonNull
} = graphql;

const ContinentType = new GraphQLObjectType({
    name: 'Continent',
    fields: () => ({
        id: {
            type: GraphQLID
        },
        details: {
            type: GraphQLString
        },
        name: {
            type: GraphQLString
        },
        country_to_show: {
            type: CountryType,
            resolve(parent, args) {
                console.log(parent);
                console.log(parent.countryID);
                return Country.findById(parent.countryID);
            }
        }
    })
});

const CountryType = new GraphQLObjectType({
    name: 'Country',
    fields: () => ({
        id: {
            type: GraphQLID
        },
        name: {
            type: GraphQLString
        },
        flag: {
            type: GraphQLString
        },
        countryCode: {
            type: GraphQLString
        },
        details: {
            type: GraphQLString
        }
    })
});

const RootQuery = new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {

        continent: {
            type: ContinentType,
            args: {
                id: {
                    type: GraphQLID
                }
            },
            resolve(parent, args) {
                return Continent.findById(args.id);
            }
        },

        country: {
            type: CountryType,
            args: {
                id: {
                    type: GraphQLID
                }
            },
            resolve(parent, args) {
                return Country.findById(args.id);
            }
        },

        countrys: {
            type: new GraphQLList(CountryType),
            resolve(parent, args) {
                return Country.find({});
            }
        },

        contintens: {
            type: new GraphQLList(ContinentType),
            resolve(parent, args) {
                return Continent.find({});
            }
        },

    }

});

const Mutation = new GraphQLObjectType({
    name: 'Mutation',
    fields: {

        addContinent: {
            type: ContinentType,
            args: {
                name: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                details: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                countryID: {
                    type: new GraphQLNonNull(GraphQLList(GraphQLString))
                }
            },
            resolve(parent, args) {
                let continent = new Continent({
                    name: args.name,
                    details: args.details,
                    countryID: args.countryID
                });
                return continent.save();
            }
        },
        addCountry: {
            type: CountryType,
            args: {
                name: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                details: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                flag: {
                    type: new GraphQLNonNull(GraphQLString)
                },
                countryCode: {
                    type: new GraphQLNonNull(GraphQLString)
                },

            },
            resolve(parent, args) {
                let country = new Country({
                    name: args.name,
                    details: args.details,
                    countryCode: args.countryCode,
                    flag: args.flag
                });
                return country.save();
            }
        }
    }
});

module.exports = new GraphQLSchema({
    query: RootQuery,
    mutation: Mutation
});

When I try to add a new Continent I can see on the database that the records are stored

{
    "_id": {
        "$oid": "5b60dea3ff0eba10ada3cbff"
    },
    "countryID": [
        "5b5cd39951017b08d3e1303a",
        "5b5cd3c77640c708edbcbf45"
    ],
    "name": "something",
    "details": "something",
    "__v": 0
}

But upon execution of the addContinent mutation in GrapiQL

mutation{
addContinent(name:"something",details:"something",countryID:["5b5cd39951017b08d3e1303a","5b5cd3c77640c708edbcbf45"]){
  name
  country_to_show{
    name
  }
}
}

I cannot see the nested the nested results in country_to_show I only get one country name in the result query instead of two I saved and cannot understand why?

{
  "data": {
    "addContinent": {
      "name": "something",
      "country_to_show": {
        "name": "albania"
      }
    }
  }
}

I believe it has to do with the fact that country_to_show in the ContinentType searches for a single country in the database but I cannot pinpoint for a solution even when I try to return a list of countries in the result query upon running the mutation I get null instead.

Andi Domi
  • 731
  • 2
  • 19
  • 48

1 Answers1

1

You are close. Here is some modified code that should work:

const continentSchema = new Schema({
  name: String,
  details: String
});
const Continent = model('Continent', continentSchema);

const countrySchema = new Schema({
  name: String,
  details: String,
  flag: String,
  continents: [{
    type: Schema.Types.ObjectId,
    ref: 'Continent'
  }]
});
const Country = model('Country', countrySchema);

const ContinentType = new GraphQLObjectType({
  name: 'Continent',
  fields: () => ({
    id: {
      type: GraphQLID
    },
    details: {
      type: GraphQLString
    },
    name: {
      type: GraphQLString
    },
    countries: {
      type: new GraphQLList(CountryType),
      resolve: (parent, args) => {
        return Country.find({ continents: parent.id });
      }
    }
  })
});

const CountryType = new GraphQLObjectType({
  name: 'Country',
  fields: () => ({
    id: {
      type: GraphQLID
    },
    name: {
      type: GraphQLString
    },
    flag: {
      type: GraphQLString
    },
    details: {
      type: GraphQLString
    },
    continents: {
      type: new GraphQLList(ContinentType),
      resolve: (parent, args) => {
        return Continent.find({
          '_id': { $in: parent.continents }
        });
      }
    }
  })
});

const RootQuery = new GraphQLObjectType({
  name: 'RootQueryType',
  fields: {

    continent: {
      type: ContinentType,
      args: {
        id: {
          type: new GraphQLNonNull(GraphQLID)
        }
      },
      resolve: (parent, args) => {
        return Continent.findById(args.id);
      }
    },

    country: {
      type: CountryType,
      args: {
        id: {
          type: new GraphQLNonNull(GraphQLID)
        }
      },
      resolve: (parent, args) => {
        return Country.findById(args.id);
      }
    },

    countries: {
      type: new GraphQLList(CountryType),
      resolve: (parent, args) => {
        return Country.find({});
      }
    },

    continents: {
      type: new GraphQLList(ContinentType),
      resolve: (parent, args) => {
        return Continent.find({});
      }
    },

  }

});

const Mutation = new GraphQLObjectType({
  name: 'Mutation',
  fields: {

    addContinent: {
      type: ContinentType,
      args: {
        name: {
          type: new GraphQLNonNull(GraphQLString)
        },
        details: {
          type: new GraphQLNonNull(GraphQLString)
        }
      },
      resolve: (parent, args) => {
        let continent = new Continent({
          name: args.name,
          details: args.details
        });
        return continent.save();
      }
    },

    addCountry: {
      type: CountryType,
      args: {
        name: {
          type: new GraphQLNonNull(GraphQLString)
        },
        details: {
          type: new GraphQLNonNull(GraphQLString)
        },
        flag: {
          type: new GraphQLNonNull(GraphQLString)
        },
        continents: {
          type: new GraphQLNonNull(new GraphQLList(GraphQLID))
        },
      },
      resolve: (parent, args) => {
        let country = new Country({
          name: args.name,
          details: args.details,
          continents: args.continents,
          flag: args.flag
        });
        return country.save();
      }
    }
  }
});

This will allow a many-to-many relationship between continents and countries.

Brian Adams
  • 43,011
  • 9
  • 113
  • 111
  • first of all thank you for your reply! As I can see here you created one to many relationship from the country point of view, where a country has the ID of a continent. But what I am really aiming for is for a continent to several ID of countries, because I want to create soon after this a many to many relationship where a continent can have different countries and a country can have different continents but i am not able to do something like that so far :/ – Andi Domi Aug 03 '18 at 18:11
  • 1
    @AndiDomi ah, gotcha. I updated the code to allow many-to-many relationships between continents and countries. I kept the relationship data in Country so that you can add the continents first, then add countries with the IDs of the continent (or continents) they are in. See if this covers what you need – Brian Adams Aug 03 '18 at 19:36