0
votes

I have the following structure. Every Account can have one security type.
So its 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.

Any advise would be appreciated

1

1 Answers

1
votes

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

enter image description here