recently I started working on GraphQL, I am able to insert data in flat schema without any problem but when it comes to an Array of data I am getting an error like
{ "errors": [ { "message": "Must be input type" } ]}
I am testing my query using postman, my mutation query is
mutation M {
AddEvent
(
title: "Birthday event"
description:"Welcome to all"
media:[{url:"www.google.com", mediaType:"image" }]
location:[{address:{state:"***", city:"****"}}]
)
{title,description,media,location,created,_id}}
This is my Event Schema:
EventType = new GraphQLObjectType({
name: 'Event',
description: 'A Event',
fields: () => ({
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
id: {
type: GraphQLString,
description: 'The id of the event.',
},
title: {
type: GraphQLString,
description: 'The title of the event.',
},
description: {
type: GraphQLString,
description: 'The description of the event.',
},
media:{
type:new GraphQLList(mediaType),
description:'List of media',
},
location:{
type:new GraphQLList(locationType),
description:'List of location',
}
})
});
// Media Type
export var mediaType = new GraphQLObjectType({
name: 'Media',
description: 'A Media',
fields: () => ({
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
url:{
type: GraphQLString,
description: 'The url of the event.',
},
mediaType:{
type: GraphQLString,
description: 'The mediaTypa of the event.',
}
})
});
// Location Type
export var locationType = new GraphQLObjectType({
name: 'Location',
description: 'A location',
fields: () => ({
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
address:{
type: GraphQLString,
description: 'The address.',
},
state:{
type: GraphQLString,
description: 'The state.',
},
city:{
type: GraphQLString,
description: 'The city.',
},
zip:{
type: GraphQLString,
description: 'The zip code.',
},
country:{
type: GraphQLString,
description: 'The country.',
}
})
});
Mongoose Schema:
var EventSchema = new mongoose.Schema({
title: {
required: true,
type: String,
trim: true,
match: /^([\w ,.!?]{1,100})$/
},
description: {
required: false,
type: String,
trim: true,
match: /^([\w ,.!?]{1,100})$/
},
media: [{
url: {
type: String,
trim: true
},
mediaType: {
type: String,
trim: true
}
}],
location: [{
address: {
type: String
},
city: {
type: String
},
state: {
type: String
},
zip: {
type: String
},
country: {
type: String
}
}]
})
Mutation Type:
addEvent: {
type: EventType,
args: {
_id: {
type: GraphQLString,
description: 'The id of the event.',
},
title: {
type: GraphQLString,
description: 'The title of the event.',
},
description: {
type: GraphQLString,
description: 'The description of the event.',
},
media:{
type:new GraphQLList(mediaType),
description:'List of media',
},
location:{
type:new GraphQLList(locationType),
description:'List of media',
},
created: {
type: GraphQLInt,
description: 'The created of the user.',
}
},
resolve: (obj, {title,description,media,location,created,_id}) => {
let toCreateEvent = {
title,
description,
created:new Date(),
start: new Date(),
media,
location,
_id,
};
return mongo()
.then(db => {
return new Promise(
function(resolve,reject){
let collection = db.collection('events');
collection.insert(toCreateEvent, (err, result) => {
db.close();
if (err) {
reject(err);
return;
}
resolve(result);
});
})
});
}
}
Your issue is that when you define mutations, all types must be input types, hence the error you get
"Must be input type"
. So in here (from your mutation):GraphQLList
,mediaType
andlocationType
must be input types.GraphQLList
is already an input type (see here https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82 to see the list of GraphQL types considered as input types).However your types
mediaType
andlocationType
are ofGraphQLObjectType
type, which is not an input type but if you look at the list of input types again: https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L74-L82, you'll findGraphQLInputObjectType
which is an object input type, so, what you need to do is to replacemediaType
andlocationType
by their "input" version.What I suggest to do is to create
mediaInputType
andlocationInputType
which would have the same field structure asmediaType
andlocationType
but created withnew GraphQLInputObjectType({...
instead ofnew GraphQLObjectType({...
and use them in your mutation.I ran into the same issue and I solved it like that, feel free to comment if you have any question.
I ran into the same problem - I did not know how to specify array of objects in the input definition. So for those who wants to see a "text" schema solution:
to have an array of Books in your input type
you can not just add
books: [Book!]
inside the input statement, you will need deliberately create input type containing needed fields (duplicate if you like):and then you can: