Search code examples
node.jsexpressgraphqllodashgraphiql

How to use arrays Schema Types for GraphQL


Trying out GraphQL for the first time, and I'd like for one Schema Type to have access to an array of objects within another Schema Type. I'm using local data and lodash to test this before I wire it up to MongoDB. I'm getting a few errors regarding my attempts at it. I know I'm close. Any assistance would be appreciated.

The following was my latest attempt. I accessed the GraphQLList using express-graphql and used GraphQLID to access the second schema.

schema.js

var projects = [
{
    name: "Title 1",
    subtitle: "Subtitle 1",
    summary: "Lorem ipsum....",
    languageId: ["4", "2"],
    id: "1"
},
...

var languages = [
{ name: "Javascript", id: "1" },
{ name: "HTML", id: "2" },
{ name: "CSS", id: "3" },
{ name: "Python", id: "4" },
]
...

const ProjectType = new GraphQLObjectType({
name: 'Project',
fields: () => ({
    id: { type: GraphQLID },
    name: { type: GraphQLString },
    subtitle: { type: GraphQLString },
    summary: { type: GraphQLString },
    languages: {
        type: new GraphQLList(GraphQLID),
        resolve(parent, args) {
            console.log(parent)
            return _.find(languages, { id: parent.languageId })
        }
    }
})
});

const LanguageType = new GraphQLObjectType({
name: 'Language',
fields: () => ({
    id: { type: GraphQLID },
    name: { type: GraphQLString },
     })
});

//Root Queries
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
    project: {
        type: ProjectType,
        args: { id: { type: GraphQLID } },
        resolve(parent, args) {

           return _.find(projects, { id: args.id });
        }
    },
    language: {
        type: LanguageType,
        args: { id: { type: GraphQLID } },
        resolve(parent, args) {

            return _.find(languages, { id: args.id })
          }
        }
    }
});

The intention was to bring up a list of languages used in that project in Graphiql that would look something like this...

    {
    "data": {
    "project": {
      "name": "Project 1"
      languages{
          names{
             "Python"
             "HTML" 
              }
            }
         }
        }
       }

Instead I'm getting the following...

    {
  "errors": [
    {
      "message": "Syntax Error: Expected Name, found }",
      "locations": [
        {
          "line": 7,
          "column": 7
        }
      ]
    }
  ]
}

I reformatted the resolve to hard code an array of languages, and that works, but it's not functional. Any suggestions would be greatly appreciated. Thank you all for your time.


Solution

  • I'm not sure what query you're trying to make. But in order to return Languages nested in Projects, you should change the return type of the languages field.

    Something like:

    const ProjectType = new GraphQLObjectType({
        name: 'Project',
        fields: () => ({
            id: {type: GraphQLID},
            name: {type: GraphQLString},
            subtitle: {type: GraphQLString},
            summary: {type: GraphQLString},
            languages: {
    
                // change this type to LanguageType
                type: new GraphQLList(LanguageType),
                resolve(parent, args) {
                    // No need to lodash here
                    return languages.filter((language) => {
                        return  parent.languageId.includes(language.id)
                    })
                }
            }
        })
    });