I have the following structure. Every Account can have one security type. So it's a one-to-many from SecurityType to Account. Everything works using the code
File: AccountSchema.js
const SecurityType = require('./LookupSchema').SecurityType;
console.log(Account);
const Account = new GraphQLObjectType({
name: 'Account',
description: 'Account access',
fields: () =>
({
id: {
type: GraphQLString
},
security_type:
{
type: SecurityType,
resolve(parent, args, ast){
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [parent.security_type_id];
db.query(db.connection, `SELECT * FROM lookups.security_type WHERE id = $1`, parameters)
.then(result =>
{
resolve(result.entrys.rows[0]);
})
.catch(err =>
{
reject(err.message);
});
});
}
}
})
});
module.exports = {
Account : Account
}
File: LookupSchema.js
const Account = require('./AccountSchema').Account;
console.log(Account);
const SecurityType = new GraphQLObjectType({
name: 'SecurityType',
description: 'Used to for specifying security type',
fields: () =>
({
id: {
type: GraphQLString
}
})
});
module.exports = {
SecurityType: SecurityType
}
File: Query.js
const Query = new GraphQLObjectType({
name: 'Query',
description: 'Root query object',
fields: () => ({
accounts: {
type: new GraphQLList(Account),
resolve(root, args, ast) {
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [];
db.query(db.connection, `SELECT * FROM accounts.account`, parameters)
.then(result =>
{
console.log(result);
resolve(result.entrys.rows);
})
.catch(err =>
{
console.log(err);
reject(err.message);
});
});
}
},
securityTypes: {
type: new GraphQLList(SecurityType),
resolve(root){
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [];
db.query(db.connection, `SELECT * FROM lookups.security_type`, parameters)
.then(result =>
{
resolve(result.entrys.rows);
})
.catch(err =>
{
reject(err.message);
});
});
}
}
})
});
The problem I have is when I add to the file LookupSchema.js the accounts
const SecurityType = new GraphQLObjectType({
name: 'SecurityType',
description: 'Used to for specifying security type',
fields: () =>
({
id: {
type: GraphQLString
},
accounts: {
type: new GraphQLList(Account),
resolve(parent, args, ast){
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [parent.id];
db.query(db.connection, `SELECT * FROM accounts.account WHERE security_type_id = $1`, parameters)
.then(result =>
{
resolve(result.entrys.rows);
})
.catch(err =>
{
reject(err.message);
});
});
}
}
})
});
I get the following error when I start the service
Error: Can only create List of a GraphQLType but got: undefined.
I put console.log for each Account and SecurityType to check for the import and I noticed in LookupSchema, Account is undefined. I did some research and this might be a circular issue but not quite sure a solution for it.
To avoide the Cyclic Problem you can use the require function inside the fields()
function.
So, Inside AccountSchema.js
fields:()
function will first import
the SecurityType
then only we will be using the the other fields with the return {}
, same for other files.
AccountSchema.js
const {
GraphQLObjectType,
GraphQLString,
} = require('graphql');
const Account = new GraphQLObjectType({
name: 'Account',
description: 'Account access',
fields: () => {
const SecurityType = require('./LookUpSchema');
return {
id: {
type: GraphQLString,
},
security_type:
{
type: SecurityType,
resolve(parent, args, ast) {
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [parent.security_type_id];
db.query(db.connection, 'SELECT * FROM lookups.security_type WHERE id = $1', parameters)
.then((result) => {
resolve(result.entrys.rows[0]);
})
.catch((err) => {
reject(err.message);
});
});
},
},
};
},
});
module.exports = Account;
LookUpSchema.js
const {
GraphQLObjectType,
GraphQLString,
GraphQLList,
} = require('graphql');
const SecurityType = new GraphQLObjectType({
name: 'SecurityType',
description: 'Used to for specifying security type',
fields: () => {
const Account = require('./AccountSchema');
return {
id: {
type: GraphQLString,
},
accounts: {
type: new GraphQLList(Account),
resolve(parent, args, ast) {
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [parent.id];
db.query(db.connection, 'SELECT * FROM accounts.account WHERE security_type_id = $1', parameters)
.then((result) => {
resolve(result.entrys.rows);
})
.catch((err) => {
reject(err.message);
});
});
},
},
};
},
});
module.exports = SecurityType;
Query.js
const {
GraphQLList,
GraphQLObjectType,
GraphQLSchema,
} = require('graphql');
const Account = require('./AccountSchema');
const SecurityType = require('./LookUpSchema');
console.log('Account', Account);
const Query = new GraphQLObjectType({
name: 'Query',
description: 'Root query object',
fields: () => ({
accounts: {
type: new GraphQLList(Account),
resolve(root, args, ast) {
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [];
db.query(db.connection, 'SELECT * FROM accounts.account', parameters)
.then((result) => {
console.log(result);
resolve(result.entrys.rows);
})
.catch((err) => {
console.log(err);
reject(err.message);
});
});
},
},
securityTypes: {
type: new GraphQLList(SecurityType),
resolve(root) {
return new Promise((resolve, reject) => {
const db = ast.db;
const parameters = [];
db.query(db.connection, 'SELECT * FROM lookups.security_type', parameters)
.then((result) => {
resolve(result.entrys.rows);
})
.catch((err) => {
reject(err.message);
});
});
},
},
}),
});
const schema = new GraphQLSchema({
query: Query,
// mutation: MutationType,
});
module.exports = schema;
GraphiQL