I am trying to add nested object data to mongodb database using graphql and also fetch the data using the code below
........................................................................................................................................................................................................
const graphql = require('graphql');
const Pricing = require('../models/pricing');
const { GraphQLObjectType, GraphQLString, GraphQLID,
GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLSchema } = graphql;
const PrcingType = new GraphQLObjectType({
name:'Pricing',
fields: () => ({
monthly:{
starter: {
type: {type: GraphQLString},
},
scale: {
type: {type: GraphQLString},
price: {type: GraphQLString},
},
},
quarterly: {
starter: {
type: {type: GraphQLString},
},
scale: {
type: {type: GraphQLString},
price: {type: GraphQLString},
},
},
})
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
pricings: {
type: new GraphQLList(PrcingType),
resolve(parent, args){
return Pricing.find({});
},
},
}
});
const Mutation = new GraphQLObjectType({
name: 'Mutation',
fields: {
addPricing: {
type: PrcingType,
args: {
monthly:{
starter: {
type: {type: GraphQLString},
},
scale: {
type: {type: GraphQLString},
price: {type: GraphQLString},
},
},
quarterly: {
starter: {
type: {type: GraphQLString},
},
scale: {
type: {type: GraphQLString},
price: {type: GraphQLString},
},
},
},
resolve(parent, args){
let pricing = new Pricing({
monthly:{
starter: {
type: {type: GraphQLString},
},
scale: {
type: {type: GraphQLString},
price: {type: GraphQLString},
},
},
quarterly: {
starter: {
type: {type: GraphQLString},
},
scale: {
type: {type: GraphQLString},
price: {type: GraphQLString},
},
},
});
return pricing.save();
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery,
mutation: Mutation
});
But when I run the grapghql server I get this error
{
"errors": [
{
"message": "The type of Pricing.monthly must be Output Type but got: undefined."
},
{
"message": "The type of Pricing.quarterly must be Output Type but got: undefined."
},
{
"message": "The type of Mutation.addPricing(monthly:) must be Input Type but got: undefined."
},
{
"message": "The type of Mutation.addPricing(quarterly:) must be Input Type but got: undefined."
}
]
}
What am I doing wrong?
Related
i am working on a project based on GraphQL API with nodejs And mongoose
so i have this Model Below :
const mongoose = require('mongoose')
const BreakingNewsSchema = new mongoose.Schema({
MainInfo:{
content:{type:String,required:true},
ParentCategory:{
type: mongoose.Schema.Types.ObjectId,
ref: 'ArticleCategory',
required: true
},
category:{
type: mongoose.Schema.Types.ObjectId,
ref: 'ArticleCategory',
required: true
},
},
options:{
clickable:{type:Boolean,required:true},
link:{type:String,required:false},
isActive:{type:Boolean,required:true,default:true}
},
infos:{
createdAt: { type: String, required: true},
updateDate: {type: String, required: false},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
},
updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: false,
}}} ,{
timestamps: true})
module.exports = mongoose.model("BreakingNews", BreakingNewsSchema)
and i have this GraphQL Schema here :
const BreakingType = new GraphQLObjectType({
name: "BreakingNews",
fields: () => ({
id: {
type: GraphQLID
},
MainInfo: {
type: new GraphQLObjectType({
name: "BreakingMainInfo",
fields: () => ({
content: {
type: GraphQLString
},
ParentCategory: {
type: CategoryType,
resolve(parent, args) {
return Category.findById(parent.MainInfo.parentCategory)
}
},
category: {
type: CategoryType,
resolve(parent, args) {
return Category.findById(parent.MainInfo.category)
}
}
})
})
},
options: {
type: new GraphQLObjectType({
name: "BreakingOptions",
fields: () => ({
clickable: {
type: GraphQLBoolean
},
link: {
type: GraphQLString
},
isActive: {
type: GraphQLBoolean
}
})
})
},
})})
For the breakingNews Collection in Mongodb
and below i have the Category Collection ... so here is the Category Model :
const CategorySchema = new mongoose.Schema({
MainInfo:{
title: {
type: String,
required: true,
unique: true
},
slug: {
type: String,
required: false,
unique: true
},
},
seo:{
metaDescription: { type: String, required: false },
metaKeywords: [{
type: String,
required: false
}]
},
options:{
isParent:{type:Boolean,required:true},
isEnded:{type:Boolean,required:true},
parentCategory: {
type: mongoose.Schema.Types.ObjectId,
ref: "ArticleCategory",
required: false,
set: v => v === '' ? null : v
}
},
info:{
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
},
updatedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: false
},
articleCount:{type:Number,required:false},
oldId: { type: String, required: false }
}}, {
timestamps: true})
module.exports = mongoose.model("ArticleCategory", CategorySchema)
And finally i have the ArticleCategory Schema for GraphQL :
const CategoryType = new GraphQLObjectType({
name: "ArticleCategory",
fields: () => ({
id: {
type: GraphQLID
},
MainInfo: {
type: new GraphQLObjectType({
name: "ArticleCategoryMainInfo",
fields: () => ({
title: {
type: GraphQLString
},
slug: {
type: GraphQLString
}
})
})
},
seo: {
type: new GraphQLObjectType({
name: "ArticleCategorySeo",
fields: () => ({
metaDescription: {
type: GraphQLString
},
metaKeywords: {
type: new GraphQLList(GraphQLString)
}
})
})
},
options: {
type: new GraphQLObjectType({
name: "ArticleCategoryOptions",
fields: () => ({
isParent: {
type: GraphQLBoolean
},
isEnded: {
type: GraphQLBoolean
},
parentCategory: {
type: CategoryType,
resolve(parent, args) {
return Category.findById(parent.options.parentCategory)
}
}
})
})
}
})})
The problem is when i try to execute this query on graphQL:
query{
ActiveBreakingNews{
id
MainInfo{
content
ParentCategory {
id
}
category{
id
}
}
}
}
I get this error Cannot read properties of undefined (reading 'category') or Cannot read properties of undefined (reading 'category')
i find out its a problem find resolve function in the schema ... but i don't know what the wrong and what should i do to fix it ... please Help and thanks in advance
I am trying to fetch the below response using graphql
....................................................................................................................................................................................................
{
"monthly": {
"starter": {
"type": "Starter",
"price": "200",
},
"scale": {
"type": "Scale",
"price": "540",
},
"organization": {
"type": "Organization",
"price": "1600",
},
"custom": {
"type": "Custom",
}
},
"_id": "62b3afea60638efd887210b5",
}
Normally with express I fetch the response with the code below
exports.getPricing = async (req, res) => {
try {
const pricing = await Pricing.find({});
return res.status(200).json(_.head(pricing));
} catch (error) {
return res.status(500).json(error.message);
}
};
But I tried using graphql to fetch same response using the code below
const { GraphQLObjectType, GraphQLString, GraphQLList, GraphQLSchema } = graphql;
const PrcingType = new GraphQLObjectType({
name:'Pricing',
fields: () => ({
monthly:{
starter: {
type: {type: GraphQLString},
price: {type: GraphQLString},
description: {type: GraphQLString},
chargeAmount: {type: GraphQLString},
interviewTemplate: {type: GraphQLString},
customQuestions: {type: GraphQLString},
yearlyPrice: {type: GraphQLString},
},
scale: {
type: {type: GraphQLString},
price: {type: GraphQLString},
description: {type: GraphQLString},
included: {type: GraphQLString},
chargeAmount: {type: GraphQLString},
interviewTemplate: {type: GraphQLString},
customQuestions: {type: GraphQLString},
yearlyPrice: {type: GraphQLString},
},
organization: {
type: {type: GraphQLString},
price: {type: GraphQLString},
description: {type: GraphQLString},
included: {type: GraphQLString},
chargeAmount: {type: GraphQLString},
interviewTemplate: {type: GraphQLString},
customQuestions: {type: GraphQLString},
yearlyPrice: {type: GraphQLString},
},
custom: {
type: {type: GraphQLString},
price: {type: GraphQLString},
description: {type: GraphQLString},
included: {type: GraphQLString},
chargeAmount: {type: GraphQLString},
interviewTemplate: {type: GraphQLString},
customQuestions: {type: GraphQLString},
yearlyPrice: {type: GraphQLString},
}
},
})
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
books: {
type: new GraphQLList(PrcingType),
resolve(parent, args){
return Pricing.find({});
},
},
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
But am getting error showing
{
"errors": [
{
"message": "The type of Pricing.monthly must be Output Type but got: undefined."
}
]
}
I have problem with some parts of my code:
const BookType = new GraphQLObjectType({
name: "Book",
fields: () => ({
id: {type: GraphQLID},
title: {type: GraphQLString},
author: {type: GraphQLString},
})
})
const fQuery = new GraphQLObjectType({
name: "firstQuery",
fields: {
books: {
type: new GraphQLList(BookType),
resolve(parent, args){
return Book.find({});
}
},
book: {
type: BookType,
args: {id: {type: GraphQLID}},
resolve(parent, args){
return Book.findById(args.id);
}
},
author: {
type: BookType,
args: {author: {type: GraphQLString}},
resolve(parent, args){
return ??????????
}
},
}
})
I don't know how to find book by author.
Next thing - mutations:
const Mutation = new GraphQLObjectType({
name: "Mutation",
fields: {
add: {
type: BookType,
args: {
title: {type: GraphQLString},
author: {type: GraphQLString},
},
resolve(parent,args){
let book = new Book({
title:args.title,
author:args.author,
})
return book.save()
}
},
update: {
type: BookType,
args: {
title: {type: GraphQLString},
author: {type: GraphQLString},
},
resolve(parent, args){
return Book.findByIdAndUpdate(args.id, {
title: args.title,
author: args.author
})
}
},
del: {
type: BookType,
args: {
id: {type: GraphQLID},
},
resolve(parent,args){
return Book.findByIdAndDelete(args.id)
}
}
}
});
Update does not work. Delete removes the first item, not the selected one by ID. This is my homework assignment. I've been sitting on this for a few hours now and can't seem to get it right.
Do anyone of you know how to fix this?
thanks in advance!
UPDATE: Searching by author does not work. I was able to fix the rest.
You also need an author GraphQLObjectType and if you store the id of the author in your books you can add a new field in author
EDIT: Also you can try find by name (but it must be unique or you will have conflicted results)
booksByAuthor: {
type: GraphQLList(BookType),
async resolve(parent, args) {
return Books.find( { id:parent.id } )
},
}
So will be something like
const AuthorType = new GraphQLObjectType({
name: 'Author',
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
booksByAuthor: {
type: GraphQLList(BookType),
async resolve(parent, args) {
return Books.find({ id: parent.id });
},
},
}),
});
I don't see the id as argument in your mutation. You need to pass the id.
update: {
type: BookType,
args: {
id:{type: GraphQLID}
title: {type: GraphQLString},
author: {type: GraphQLString},
},
resolve(parent, args){
return Book.findByIdAndUpdate(args.id, {
title: args.title,
author: args.author
})
}
},
I'm new to this as well but I hope it helps
I'm creating a GraphQL Server using Node JS.
I'm trying to replicate the mongo Schema which has a nested object purely for organisation. This is my mongo schema:
var plansSchema = new Schema({
planName: {
type: String,
required: [true, "Plan name is required"]
},
pricing: {
monthly: Number,
scanEnvelope: Number,
initalScan: Number,
perPage: Number,
forwardMail: Number,
forwardParcel: Number,
shred: Number,
perMonthPerGram: Number,
freeStorePerGram: Number,
setup: Number,
idFree: Number
},
expires: Number,
private: Boolean,
deleted: Boolean,
date: { type: Date, default: Date.now },
});
I'm trying to replicate this in a GraphQL schema, so far I have the following:
const PlanType = new GraphQLObjectType({
name: "Plan",
fields: () => ({
id: { type: GraphQLString },
planName: { type: GraphQLString },
pricing: new GraphQLObjectType({
name: "Pricing",
fields: () => ({
expires: { type: GraphQLInt },
private: { type: GraphQLBoolean },
monthly: { type: GraphQLInt },
scanEnvelope: { type: GraphQLInt },
initalScan: { type: GraphQLInt },
perPage: { type: GraphQLInt },
forwardMail: { type: GraphQLInt },
forwardParcel: { type: GraphQLInt },
shred: { type: GraphQLInt },
perMonthPerGram: { type: GraphQLInt },
freeStorePerGram: { type: GraphQLInt },
setup: { type: GraphQLInt },
idFree: { type: GraphQLInt }
})
})
})
});
But I'm getting the following errro in GraphiQL
{
"errors": [
{
"message": "The type of Plan.pricing must be Output Type but got: undefined."
}
]
}
Each field in the GraphQLFieldConfigMapThunk or GraphQLFieldConfigMap that you set as your fields must be a GraphQLFieldConfig object that includes properties like type, args, resolve, etc. You cannot set a field to a GraphQLObjectType like you're doing with the pricing field. In other words, your code should look more like this:
const PricingType = new GraphQLObjectType({
name: "Pricing",
fields: () => ({
expires: { type: GraphQLInt },
private: { type: GraphQLBoolean },
monthly: { type: GraphQLInt },
scanEnvelope: { type: GraphQLInt },
initalScan: { type: GraphQLInt },
perPage: { type: GraphQLInt },
forwardMail: { type: GraphQLInt },
forwardParcel: { type: GraphQLInt },
shred: { type: GraphQLInt },
perMonthPerGram: { type: GraphQLInt },
freeStorePerGram: { type: GraphQLInt },
setup: { type: GraphQLInt },
idFree: { type: GraphQLInt }
})
})
const PlanType = new GraphQLObjectType({
name: "Plan",
fields: () => ({
id: { type: GraphQLString },
planName: { type: GraphQLString },
pricing: { type: PricingType },
}),
})
I'm attempting to filter data with geo distance.My mongoose schema is:
'use strict';
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var beautifyUnique = require('mongoose-beautiful-unique-validation');
var mongoosastic = require("mongoosastic");
var schema = new Schema({
vendor_id: { type: Schema.Types.ObjectId, ref: 'Vendor' },
category: { type: Schema.Types.ObjectId, ref: 'Category' },
name: { type: String, required: 'Business Name is required' }, // es_indexed: true },
contact: {
contact_name: { type: String, required: 'Name is required' },
email: { type: String, required: 'Email is required' },
s_email: String,
mobile: { type: String, required: 'Mobile No. is required' },
s_mobile: String,
},
images: [{
title: String,
desc: String,
key_large: String,
url_large: String,
key_thumb: String,
url_thumb: String
}],
cover_image: String,
description: String,
seat_capacity: Number,
float_capacity: Number,
address: {
address1: String,
city: String,
state: String,
country: String,
pin: Number
},
geometry: {
type: [Number]
// index: "2dsphere",
},
events: [{ type: Schema.Types.ObjectId, ref: 'Event' }],
highlights: [{ type: String }],
advanced_percentage: Number,
taxes: {
food: Number,
other: Number
},
cancellable: Boolean,
time_slots: [{
text: String,
slot: String
}],
min_Order_quantity: String,
outside_catering: Boolean,
outside_decorators: Boolean,
alcohol_allowed: Boolean,
terms: String,
aminities: [{ type: Schema.Types.ObjectId, ref: 'Aminity' }],
sub_categories: [{ type: String }],
status: { type: String, default: 'draft' },
verifiedBy: { type: Schema.Types.ObjectId, ref: 'SuperAdmin' },
verifyTime: { type: Date },
isAvailable: Boolean,
isBlocked: { type: Boolean, default: false },
blockedBy: { type: Schema.Types.ObjectId, ref: 'SuperAdmin' },
blockReason: String,
created_at: { type: Date, default: Date.now() },
updated_at: { type: Date },
version: { type: Number }
});
schema.plugin(mongoosastic, {
hosts: [
'localhost:9200'
]
});
schema.plugin(beautifyUnique);
// enables beautifying
var Business = module.exports = mongoose.model('BusinessDetail', schema);
Business.createMapping({
"mappings": {
"businessdetail": {
"properties": {
"geometry": {
"type": "geo_point"
}
}
}
}
}, function(err, mapping) {
if (err) {
console.log('error creating mapping (you can safely ignore this)');
console.log(err);
} else {
console.log('mapping created!');
console.log(mapping);
}
});
And my search code is
BusinessDetail.search({
"bool": {
"must": {
"match_all": {}
},
"filter": {
"geo_distance": {
"distance": "200km",
"geometry": [lon, lat]
}
}
}
},
function(err, business) {
console.log('err:', err);
console.log('data:', business);
res.send({
success: true,
data: business
});
});
I've tried many combinations of filtering.But it give the error
err: { Error: [query_shard_exception] field [geometry] is not a
geo_point field, with { index_uuid="6e4ptkf0TFWwp1IN3tIRbA" &
index="businessdetails" }
at respond (C:\eventbucket\eb-server\node_modules\mongoosastic\node_modules\
elasticsearch\src\lib\transport.js:289:15)
at checkRespForFailure (C:\eventbucket\eb-server\node_modules\mongoosastic\n
ode_modules\elasticsearch\src\lib\transport.js:248:7)
at HttpConnector. (C:\eventbucket\eb-server\node_modules\mongoosa
stic\node_modules\elasticsearch\src\lib\connectors\http.js:164:7)
at IncomingMessage.wrapper (C:\eventbucket\eb-server\node_modules\lodash\lod ash.js:4968:19)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:185:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:74:11)
at process._tickDomainCallback (internal/process/next_tick.js:122:9) status: 400, displayName:
'BadRequest', message: '[query_shard_exception] field [geometry] is
not a geo_point field, w ith { index_uuid="6e4ptkf0TFWwp1IN3tIRbA" &
index="businessdetails" }', path:
'/businessdetails/businessdetail/_search', query: {}, body:
'{"query":{"bool":{"must":{"match_all":{}},"filter":{"geo_distance":{"di
stance":"200km","geometry":[88.36389500000001,22.572646]}}}}}',
statusCode: 400, response:
'{"error":{"root_cause":[{"type":"query_shard_exception","reason":"f
ield [geometry] is not a geo_point
field","index_uuid":"6e4ptkf0TFWwp1IN3tIRbA",
"index":"businessdetails"}],"type":"search_phase_execution_exception","reason":"
all shards
failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"i
ndex":"businessdetails","node":"iQy-hWNlTnaiUL3cUlAWVQ","reason":{"type":"query_
shard_exception","reason":"field [geometry] is not a geo_point
field","index_uui
d":"6e4ptkf0TFWwp1IN3tIRbA","index":"businessdetails"}}]},"status":400}',
toString: [Function], toJSON: [Function] } data: undefined
How to solve the error?