Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GraphQL Missing a Name

Just learning GraphQL using both node and c#. I am trying to port the C# example over to node since it will be a good learning exercise (since I don't know node or graphql that well)

I have 2 types. Account and Owner (i.e. account owner)

Everything works fine with the following (i.e. Fields for Owned Accounts (list) and First Account (single object)

module.exports = new GraphQLObjectType({
    name: 'OwnerType',
    fields: {
        Id: { type: GraphQLID},
        Name: {type: GraphQLString},
        Address: {type: GraphQLString},
        OwnedAccounts: {
            type: new GraphQLList(AccountType),
            name: "OwnedAccounts",
            resolve(obj, args, { mssqlConfig }){
                return mssql_account(mssqlConfig).getByOwnerId(obj.Id);
            }
        },
        FirstAccount: {
            type: AccountType,
            name: "FirstAccount",
            resolve(obj, args, {mssqlConfig}){
                 return mssql_account(mssqlConfig).getFirstByOwnerId(obj.Id);
            }
        }
    }
}); 

The issue arises when I try to add a field for AccountOwner to the AccountType. I get the error "One of the provided types for building the Schema is missing a name."

I have tried putting a name on everything I could see which didn't help at all.

The offending AccountType definition is:

module.exports = new GraphQLObjectType({
    name: 'AccountType',
    fields: {
        Id: { type: GraphQLID },
        Description: { type: GraphQLString },
        OwnerId: { type: GraphQLID },
        Type: { type: AccountTypeEnum },
        AccountOwner: {
               type: OwnerType,
               resolve(obj, args, { mssqlConfig }){
                    return mssql_owner(mssqlConfig).get(obj.OwnerId);
               }
        }
    }
});

If you need further info or any other code please let me know.

EDIT: If I change the declaration of the two types (Account and Owner) and put them in the same .js file then it works (see below). I have also changed the fields to return an arrow function which I believe will delay some kind of binding till after everything is loaded.

So now my question is how should I separate the types into different files. (JS isn't my strong point)

EDIT... altered Types...

const {
GraphQLObjectType,
GraphQLID,
GraphQLString,
GraphQLList
} = require('graphql');

const AccountTypeEnum = require('./accountTypeEnum');
const mssql_owner = require('../../database/mssql/owner');
const mssql_account = require('../../database/mssql/account');

const ownerType = new GraphQLObjectType({
name: 'OwnerType',
fields: () => ({
    Id: { type: GraphQLID, name: "Id"},
    Name: {type: GraphQLString, Name: "Name"},
    Address: {type: GraphQLString},
    OwnedAccounts: {
        type: new GraphQLList(accountType),
        name: "OwnedAccounts",
        resolve(obj, args, { mssqlConfig }){
            return mssql_account(mssqlConfig).getByOwnerId(obj.Id);
        }
    },
    FirstAccount: {
        type: accountType,
        name: "FirstAccount",
        resolve(obj, args, {mssqlConfig}){
             return mssql_account(mssqlConfig).getFirstByOwnerId(obj.Id);
        }
    }
})
}); 

const accountType = new GraphQLObjectType({
name: 'AccountType',
fields: () => ({
    Id: { type: GraphQLID, name: "Id" },
    Description: { type: GraphQLString, name: "Description" },
    OwnerId: { type: GraphQLID, name: "OwnerId" },
    Type: { type: AccountTypeEnum, name: "Type" },
    AccountOwnerFoo: {
           name: "Wombat",
           type: ownerType,
           resolve(parent, args, {mssqlConfig}){
                return mssql_owner(mssqlConfig).get(parent.OwnerId);
           }
    }
})
});

module.exports = {
ownerType,
accountType
}
like image 924
S Rosam Avatar asked Apr 28 '20 16:04

S Rosam


2 Answers

Node.js allows circular dependencies. Not all module systems allow this but it works in Node. The problem is, that one of the modules needs to be undefined in whatever module gets parsed first. In this case, Node.js assigns an empty object as the export of this module.

So basically you are assigning an empty object as a type sometimes - thus complaining that the type is missing the name property. The good thing though is that the reference to this object will not change if you assign properties to it. What you have to do I have answered already here and here.

like image 124
Herku Avatar answered Nov 16 '22 08:11

Herku


why this error occurred? Because you are giving the type which is not defined at the compile time. So, when the compiler tries to compile the file, it searches the type you have specified here it is AccountType. which is not compiled. That's why the OwnerType didn't get the AccountType and you are getting an error.

Simple Solution:

You need to import the AccountType inside the OwnerType file.

const AccountType = require('./AccountType.js');

before the OwenerType code. This might be helpful.

like image 1
Mayur Avatar answered Nov 16 '22 09:11

Mayur