I am learning GraphQL and I faced an error due while trying to start a server.
const graphql = require('graphql');
const _ = require('lodash');
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema
} = graphql;
const Users = [
{ id: '23', firstName: 'Bill', age: 20 },
{ id: '41', firstName: 'Jane', age: 18 }
];
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: { type: GraphQLString },
firstName: { type: GraphQLString },
age: { type: GraphQLInt }
}
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: {
type: UserType,
args: { id: { type: GraphQLString } },
resolve(parentValue, args) {
return _.find(Users, { id: args.id });
}
}
}
}
});
module.exports = new GraphQLSchema({
query: RootQuery
});
and the server.js code is here:
const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const schema = require('./schema/schema');
const app = express();
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true
}));
app.listen(4000, () => {
console.log("Server running at port 4000.");
});
The error seems to be coming from the "module.exports" section as when I comment it out the server starts without a problem.
There is syntax confusion. In RootQuery the type part under user completely covers the whole field structure, error is here.
Just remove top level type: {}.
Try this out:
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLString } },
resolve(parentValue, args) {
return _.find(Users, { id: args.id });
}
}
}
});
Related
I got this error:
"Mutation fields must be an object with field names as keys or a function which returns such an object."
I try to add user but I don't know how to make this work.
const mutation = new GraphQLObjectType({
name: "Mutation",
fileds: {
addUser: {
type: UserType,
args: {
firstName: { type: new GraphQLNonNull(GraphQLString) },
age: { type: new GraphQLNonNull(GraphQLInt) },
companyId: { type: GraphQLString }
},
resolve(parentValue, { firstName, age }) {
return axios.post("http://localhost:3000/users", { firstName, age }).then(r => r.data);
}
}
}
})
UserType is defined as follows:
const UserType = new GraphQLObjectType({
name: "User",
fields: {
id: { type: GraphQLString },
firstName: { type: GraphQLString },
age: { type: GraphQLInt },
company: {
type: CompanyType,
resolve(parentValue, args) {
return axios.get("http://localhost:3000/companies/" + parentValue.companyId).then(res => res.data)
}
}
}
})
You have a typo: "fileds" should be "fields".
i am learning GraphQL with NodeJS but getting the error.
i have develop a mongoDB and NodeJS GraphQL REST API for Understanding and Learning purpose
Here is my Code :
const graphql = require('graphql');
const user = require('../models/User');
const post = require('../models/Post');
const { GraphQLObjectType, GraphQLID, GraphQLString } = graphql;
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: { type: GraphQLID },
fname: { type: GraphQLString },
lname: { type: GraphQLString },
email: { type: GraphQLString },
posts: {
type: PostType,
resolve(parent, args) {
return 1;
}
}
})
});
const PostType = new GraphQLObjectType({
name: 'Post',
fields: () => ({
id: { type: GraphQLID },
Userid: { type: GraphQLID },
title: { type: GraphQLString },
date: { type: GraphQLString },
})
});
const RootQueryType = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLID } },
resolve(parent, args) {
return user.findById({ id: args.id });
}
},
post: {
type: PostType,
args: { id: { type: GraphQLID } },
resolve(parent, args) {
return post.findById({ id: args.id });
}
}
}
});
module.exports = new graphql.GraphQLSchema({
query: RootQueryType,
});
Please Help me to find the Solution.
Answer me to resolve this error.
This question already has an answer here:
What is the correct way to nest data within a graphql?
(1 answer)
Closed 2 years ago.
I have come across this problem in setting up my server with GraphQL, Express.js, and MongoDB. It seems like some sort of reference error, I am not sure what the issue is, I have tried looking for my answer but cannot seem to find it.
The error I am getting on GraphiQL is this, I am not sure why
{
"errors": [
{
"message": "The type of Meal.nutrition must be Output Type but got: undefined."
}
]
}
Anyway, on app.js
The code is
const express = require("express")
const app = express();
const userSchema = require("./graph-schema/userQueries")
const workoutSchema = require("./graph-schema/workoutQueries")
const mealSchema = require("./graph-schema/mealQueries")
const mongoose = require("mongoose")
const {mergeSchemas} = require("graphql-tools")
//connect to mongoDB atlase database
mongoose.connect("mongodb+srv://Z***98:*****#cluster0-epauj.mongodb.net/test?retryWrites=true&w=majority")
mongoose.connection.once("open", () => {
console.log("Connected to database")
})
const combinedSchemas = mergeSchemas({
schemas: [
userSchema,
mealSchema,
workoutSchema
]
})
//this module allows express to communicate with graphql ;
//we use it as a single endpoint
const graphqlHTTP = require("express-graphql")
app.use("/graphql" , graphqlHTTP({
schema: combinedSchemas,
graphiql: true
}))
app.listen(4000, () => {
console.log(`Listening on port 4000`)
})
MealType is defined in a file called schema.js, which has all the other types (UserType, AuthType, WorkoutType), I have imported and exported I needed.
const graphql = require("graphql")
const Workout = require("../models/Workout.js")
const User = require("../models/User.js")
const Meal = require("../models/Meal")
const {GraphQLObjectType, GraphQLID, GraphQLString, GraphQLSchema, GraphQLInt, GraphQLList} = graphql;
//describes what attributes and its types, a User has in each query
const UserType = new GraphQLObjectType({
name: "User",
fields: () => ({
id: {type: GraphQLID},
name: {type: GraphQLString},
email: {type: GraphQLString},
password: {type: GraphQLString},
workouts: {
type: new GraphQLList(WorkoutType),
resolve(parent, args){
//returns all the workouts created by a user
return Workout.findById({userId: parent.id})
}
},
meals: {
type: new GraphQLList(MealType),
resolve(parent, args){
//returns all the meals created by a user
return Meal.findById({userId: parent.id})
}
}
})
})
const WorkoutType = new GraphQLObjectType({
name: "Workout",
fields: () => ({
id: {type: GraphQLID},
name: {type: GraphQLString},
reps: {type: GraphQLInt},
burnedCalories: {type: GraphQLInt},
sets: {type: GraphQLInt},
user: {
type: UserType,
resolve(parent, args){
//returns the user from the database that created the workout instance
return User.findById(parent.userId)
}
}
})
})
const AuthType = new GraphQLObjectType({
name: "Authentication",
fields: () => ({
token: {type: GraphQLString},
userId: {type: GraphQLString}
})
})
const MealType = new GraphQLObjectType({
name: "Meal",
fields: () => ({
id: {type: GraphQLID},
calories: {type: GraphQLInt},
servings: {type: GraphQLInt},
nutrition: {
carbohydrates: {type: GraphQLInt},
fats: {type: GraphQLInt},
protein: {type: GraphQLInt}
},
user: {
type: UserType,
resolve(parent, args){
//returns the user from the database that created the meal instance
return User.findById(parent.userId)
}
}
})
})
module.exports = {
AuthType,
WorkoutType,
UserType,
MealType
}
The Meal which will be saved onto MongoDB atlas looks like
const mealSchema = new Schema({
name: String,
calories: Number,
servings: Number,
nutrition: {
carbohydrates: Number,
fats: Number,
protein: Number
},
userId: String
})
And now the mutation and queries are for the meals are defined in a file called mealQueries.js
const graphql = require("graphql")
const {MealType} = require("./schema")
const Meal = require("../models/Meal.js")
const {GraphQLObjectType, GraphQLID, GraphQLString, GraphQLSchema, GraphQLInt, GraphQLList} = graphql;
const MealQuery = new GraphQLObjectType({
name: "MealQueries",
fields: () => ({
meal: {
type: MealType,
args: {id: {type: GraphQLID}},
resolve(parent, args){
return Meal.findById(args.id)
}
},
meals: {
type: new GraphQLList(MealType),
resolve(parent, args){
return Meal.find({})
}
}
})
})
const MealMutation = new GraphQLObjectType({
name: "MealMutation",
addMeal: {
type: MealType,
args: {
name: {type: GraphQLString},
servings: {type: GraphQLInt},
calories: {type: GraphQLInt},
nutrition: {
carbohydrates: {type: GraphQLInt},
proteins: {type: GraphQLInt},
fats: {type: GraphQLInt}
},
userId: {type: GraphQLID}
},
resolve(parent, args){
let meal = new Meal({
userId: args.userId,
name: args.name,
servings: args.servings,
calories: args.calories,
nutrition: {
carbohydrates: args.nutrition.carbohydrates,
fats: args.nutrition.fats,
proteins: args.nutrition.proteins
}
})
return meal.save();
}
}
})
module.exports = new GraphQLSchema({
query: MealQuery,
mutation: MealMutation
})
You can't nest fields like this:
nutrition: {
carbohydrates: {type: GraphQLInt},
fats: {type: GraphQLInt},
protein: {type: GraphQLInt}
},
You need to create a separate type. You can do so inline if you don't need to reference it elsewhere in your schema:
nutrition: new GraphQLObjectType({
name: 'Nutrition',
fields: () => ({
carbohydrates: { type: GraphQLInt },
fats: { type: GraphQLInt },
protein: { type: GraphQLInt },
}),
}),
I've set a Schema to make a GraphQL Query, and now I run the server, go to GraphQL Client, and I get the following error:
"Syntax Error: Unexpected "
line: 32.
My code is the following:
const graphql = require('graphql') const _ = require('lodash') const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema
} = graphql;
const users = [{
id: '23',
firstName: 'Thiago',
age: 36
}, {
id: '47',
firstName: 'Caroline',
age: 29
}];
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: {
type: GraphQLString
},
firstName: {
type: GraphQLString
},
age: {
type: GraphQLInt
}
}
})
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: {
id: {
type: GraphQLString
}
},
resolve(parentValue, args) {
return _.find(users, {
id: args.id
})
}
}
}
}) module.exports = new GraphQLSchema({
query: RootQuery
})
Thanks in advance for your help.
Trying to get GraphQL to work with JavaScript. Not sure where my mistake is.
My code
const graphql = require('graphql');
const _ = require('lodash');
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema
} = graphql;
const users = [
{ id: "23", firstName: "Bill", age: 20},
{ id: "47", firstName: "Sam", age: 21}
];
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: {type: GraphQLString},
firstName: {type: GraphQLString},
age:{type: GraphQLInt}
}
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: { id: { type: GraphQLString } },
resolve(parentValue, args) {
return _.find(users, { id: args.id });
}
}
}
});
module.exports = new GraphQLSchema ({
query: RootQuery
});
I am getting
{ "errors": [
{
"message": "Type RootQueryType must define one or more fields."
}
] }
Why is it not working?
you forgot to use an arrow function
const UserType = new GraphQLObjectType({
name: 'User',
fields:()=>( {
id: {type: GraphQLString},
firstName: {type: GraphQLString},
age:{type: GraphQLInt}
});
I believe your mistake is simply in your Query. You use the RootQueryType's fields object to make your query endpoints. The fields object in your case only contains one query: user. However you are trying to make a query for User, which is different.
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
// The items listed here are going to be your root query endpoints.
// Which in this case is only `user`.
user: {
type: UserType,
args: { id: { type: GraphQLString } },
resolve(parentValue, args) {
return _.find(users, { id: args.id });
}
}
}
});
So you need to make your query using user.
Additionally, you need to make sure you are making your query correctly. Basic query syntax for what you are trying to achieve looks like this:
{
user(id: "23") {
id
firstName
age
}
}
Let me know if this works for you.
Some documentation on queries:
GraphQL Queries
DevHints - GraphQL