0

According to the documentation here, the second argument to a resolver function in the graphql-tools library is an object passed into the query

http://dev.apollodata.com/tools/graphql-tools/resolvers.html#Resolver-function-signature

However, if I run graphql-tools with a version of graphql >= 0.8.0, the "object" passed as the second argument is missing some object properties. For example, arg.constructor and arg.hasOwnProperty are undefined.

In the previous version, 0.7.2, both these statements would evaluate to true:

arg.consructor === Object
arg.hasOwnProperty === 'function'

Does anyone know what is actually getting passed as the second argument, or why these properties which usually exist on JS objects are undefined?

edit below:

I can get by this by doing something like this:

async resolverFuncForMutation(root, nonObjArgs, context) {
  const args = Object.assign({}, nonObjArgs);

But I don't want to have to remember how to do that for every resolver function. Does anyone know how to if there's a way to configure that to happen in some kind of pre-resolution hook?

albertlockett
  • 204
  • 3
  • 13

1 Answers1

1

Looking at the source code, it looks like prior to 0.8.0, the object that was passed to the resolver function was initialized as {}. Now it's being initialized as Object.create(null).

You are still receiving an object, but when Object.create(null) is used, the resulting object doesn't inherit from any prototype, whereas {} inherits from the Object prototype. Methods like hasOwnProperty and toString actually belong to the prototype, not objects themselves. While most objects (little "o") you encounter will be instances of Object (big "O"), this isn't necessarily the case as you've discovered here.

There's some good discussion here around why Object.create(null) is often preferred.

As far as I know, there's no way to modify the arguments before they are passed to the resolver in the way you'd like. However, if you need them to be an Object just to utilize hasOwnProperty, it may be simpler to just refactor your code a little bit, i.e. instead of:

if (foo.hasOwnProperty('bar')) doSomething()

You can just do

if (foo.bar) doSomething()
Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183
  • Thanks man, that's it! Unfortunately I had some third party libs calling hasOwnProperty, ect. on the arguments. Ended up writing a little preprocessor for my resolver functions to traverse the arguments data structure and call something like args = `Object.assign({}, args)`. Worked like a charm – albertlockett Aug 15 '17 at 21:05