Antonyjim
Antonyjim

Reputation: 118

GraphQL Fields Undefined

Starting out with a GraphQL / Node / Express / Typescript stack, I am coming across an issue where field arguments are not being passed to the resolver function. I have two queries:

UserList:

UserList: {
        type: new GraphQLList(UserType),
        args: {
            userName: {
                type: GraphQLString
            },
            userIsLocked: {
                type: GraphQLBoolean
            },
            userIsConfirmed: {
                type: GraphQLBoolean
            },
            userAwaitingPassword: {
                type: GraphQLBoolean
            }
        },
        resolve: ((_, {fields}) => new User().where({fields}))
    }

And User:

User: {
    type: UserType,
    args: {
        userId: {
            type: GraphQLID
        }
    },
    resolve: ((_, {userId}) => new User().getById({userId}))
}

The User().where() function defaults to displaying all users if no criteria is provided. However, consider the following query and results:

query All {
  UserList(userIsLocked:true){
    userId
    userName
    userIsLocked
  }
}

// Results
{
  "data": {
    "UserList": [
      {
        "userId": "a4f1d968-52d6-4148-bf62-1e132a4defde",
        "userName": "user1",
        "userIsLocked": false
      },
      {
        "userId": "b42a1170-096a-11e9-b568-0800200c9a66",
        "userName": "administrator",
        "userIsLocked": false
      }
    ]
  }
}

Obviously, userIsLocked is not being passed the fields argument on the where() function. However, the following works:

query Individual {
  User(userId: "a4f1d968-52d6-4148-bf62-1e132a4defde") {
    userId
    userName
    userIsLocked
  }
}

// Results
{
  "data": {
    "User": {
      "userId": "a4f1d968-52d6-4148-bf62-1e132a4defde",
      "userName": "user1",
      "userIsLocked": false
    }
  }
}

When userId is logged on a request to getById(), I see {"userId":"a4f1d968-52d6-4148-bf62-1e132a4defde"} in the console. But when fields is logged on a request to where(), all that shows in the console is undefined and my query defaults to displaying all users. I can not figure out why 2 apparently equal queries would be behaving in such different ways. I have scoured the documentation for GraphQL but all I can find are sample queries and general query structure.

Upvotes: 1

Views: 8050

Answers (1)

Daniel Rearden
Daniel Rearden

Reputation: 84687

The second argument passed to the resolve function is an object the properties of which map to the arguments for that field. Let's look at the working resolver:

resolve: (_, {userId}) => new User().getById({userId})

Here, you're using object destructuring syntax to unpack the userId property from the second parameter and sign it to a variable of the same name. You then use shorthand property name syntax to create an object with the userId property (with the value of the userId variable you defined) and this object is passed to the getById method.

This is syntactically equivalent to the following function:

resolve: (_, args) => {
  const userId = args.userId
  return new User().getById({ userId: userId })
}

It's unclear from your question what ORM you're using, so I can't speak to whether you're correctly calling the where method in other resolver. However, you are definitely not unpacking any of the arguments for that field. Here's your function:

resolve: (_, {fields}) => new User().where({fields})

Which is equivalent to:

resolve: (_, args) => {
  const fields = args.fields
  return new User().where({ fields: fields })
}

Your field has the following four arguments: userName, userIsLocked, userIsConfirmed and userAwaitingPassword. fields is not a valid argument and therefore will always be undefined unless you add an argument named fields to your UserList field and actually pass it in. I'm going to hazard a guess and say your model also doesn't have a fields property. If you simply want to pass in the arguments object to the where method, you can do:

resolve: (_, fields) => new User().where(fields)

Note the lack of curly braces. Again, you haven't told us anything about what ORM you're using or the User model itself, so this still may not give you the desired results if you're not correctly using that API. However, hopefully this puts you on the right track.

Upvotes: 6

Related Questions