How to use the names in a GraphQLEnumType as the defaultValue of a GraphQL query argument?
Asked Answered
Q

3

6

When defining a query in a schema, how do I refer to a value of an GraphQLEnumType declared previously, to use it as the default value of an argument?

Let's say I've defined following ObservationPeriod GraphQLEnumType:

observationPeriodEnum = new GraphQLEnumType {
  name: "ObservationPeriod"
  description: "One of the performance metrics observation periods"
  values:
    Daily:
      value: '1D'
      description: "Daily"
    […]
}

and use it as the type of query argument period:

queryRootType = new GraphQLObjectType {
  name: "QueryRoot"
  description: "Query entry points to the DWH."
  fields:
    performance:
      type: performanceType
      description: "Given a portfolio EID, an observation period (defaults to YTD)
                    and as-of date, as well as the source performance engine,
                    return the matching performance metrics."
      args:
        period:
          type: observationPeriodEnum 
          defaultValue: observationPeriodEnum.Daily ← how to achieve this?
      […]
}

Currently I'm using the actual '1D' string value as the default value; this works:

        period:
          type: observationPeriodEnum 
          defaultValue: '1D'

But is there a way I could use the Daily symbolic name instead? I couldn't find a way to use the names within the schema itself. Is there something I overlooked?

I'm asking, because I was expecting an enum type to behave as a set of constants also, and to be able to use them like this in the schema definition:

        period:
          type: observationPeriodEnum 
          defaultValue: observationPeriodEnum.Daily

Naïve workaround:

##
# Given a GraphQLEnumType instance, this macro function injects the names 
# of its enum values as keys the instance itself and returns the modified
# GraphQLEnumType instance.
#
modifiedWithNameKeys = (enumType) ->
  for ev in enumType.getValues()
    unless enumType[ ev.name]?
      enumType[ ev.name] = ev.value
    else
      console.warn "SCHEMA> Enum name #{ev.name} conflicts with key of same
        name on GraphQLEnumType object; it won't be injected for value lookup"
  enumType

observationPeriodEnum = modifiedWithNameKeys new GraphQLEnumType {
  name: "description: "Daily""
  values:
    […]

which allows to use it as desired in schema definition:

        period:
          type: observationPeriodEnum 
          defaultValue: observationPeriodEnum.Daily

Of course, this modifier fullfils its promise, only as long as the enum names do not interfere with GraphQLEnumType existing method and variable names (which are currently: name, description, _values, _enumConfig, _valueLookup, _nameLookup, getValues, serialize, parseValue, _getValueLookup, _getNameLookup and toString — see definition of GraphQLEnumType class around line 687 in https://github.com/graphql/graphql-js/blob/master/src/type/definition.js#L687)

Quaternion answered 16/4, 2016 at 16:19 Comment(0)
B
1

I just ran into this. My enum:

const contributorArgs = Object.assign(
  {},
  connectionArgs, {
    sort: {
      type: new GraphQLEnumType({
        name: 'ContributorSort',
        values: {
          top: { value: 0 },
        },
      })
    },
  }
);

In my queries, I was doing:

... on Topic {
  id
  contributors(first: 10, sort: 'top') {
    ...
  }
}

Turns out you just don't quote the value (which after thinking about it makes sense; it's a value in the enum type, not an actual value:

... on Topic {
  id
  contributors(first: 10, sort: top) {
    ...
  }
}
Buyers answered 30/1, 2017 at 22:44 Comment(1)
Hi @Matthew Herbst, thanks for looking into this and sharing your experience – which relates to stating an enumerated literal value in a GQL query (that is, at «runtime»). My question was however about the schema declaration: how to access one of the enumerated values, using a symbol rather that duplicating the literal value, while declaring the schema itself? – that it, at «schema design time», rather that «query-time / runtime».Quaternion
C
0

It's possible to declare enum values as default inputs via the schema definition language, but it looks like you are only using the JS library APIs. You might be able to get to a solution by taking a look at the ASTs for the working example and comparing that with the AST from what your JS code is producing.

Sorry not a solution, but hope that helps!

Cosmorama answered 14/6, 2017 at 15:51 Comment(0)
C
0

I found a pull request adding a method .getValue() to enum types, which returns name and value. In your case this call:

observationPeriodEnum.getValue('Daily');

would return:

{
  name: 'Daily',
  value: '1D'
}
Comprehensive answered 12/12, 2018 at 15:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.