how to use enum in apollo-client?
Asked Answered
U

2

11

the enum define in OrderTypesEnum.gql

enum OrderTypes {
  full_buy
  pink_buy
}

import OrderTypesEnum.gql file

import OrderTypes from '@/graphql/OrderTypesEnum.gql'`

but, How to get enum in code ?

I use OrderTypes.full_buy get some error:

   self.$apollo.mutate({
        mutation: createOrder,
        variables: {
          subjectId: self.subject.id,
          types: OrderTypes.full_buy
        }
      })
Mutation createOrderMutation error: Invariant Violation: Schema type definitions not allowed in queries. Found: "EnumTypeDefinition"

the inspect of OrderTypes type enum

enter image description here

Uta answered 18/9, 2019 at 17:42 Comment(0)
C
8

Prerequisites:

< SomeEnumType > is defined in GraphQL schema (server side, no client configuration needed)

Let's assume we have:

enum SomeEnumType {
    OPTION1,
    OPTION2,
    OPTION3
}

Apollo Client should be configured appropriate way and connected with the GraphQL API.

Then on the client side:

export const OUR_MUTATION = gql`
    mutation ourMutation($foo: SomeEnumType){
        ourMutation(foo: $foo){
            bar
        }
    }    
`

Only by doing this, we can pass an enum as a variable in our query or mutation. For example, with useMutation hook we can now mutate as follows:

const [ourMutation] = useMutation(OUR_MUTATION, {
        variables: {
            foo: "OPTION2"
        },

Since the type definition in gql tag equals the definition in Schema, GraphQL recognizes a variable as an enum type despite giving it as a string.

If we want to pass an enum to variables using typescript enums we can do it as follows:

enum SomeEnumType {
    OPTION1 = 0,
    OPTION2 = 1,
    OPTION3 = 2
}

const [ourMutation] = useMutation(OUR_MUTATION, {
        variables: {
            foo: SomeEnumType[SomeEnumType.OPTION1]
        },

UPDATE: String enums and type generation

Personally, I recommend using string enums if possible. The usage of string enums is more straightforward.

enum SomeEnumType {
    OPTION1 = "OPTION1",
    OPTION2 = "OPTION2",
    OPTION3 = "OPTION3"
}

...
...

variables: {
    foo: SomeEnumType.OPTION1
}

For next-level coding, enum types, and all other type definitions can be automatically generated to the frontend with graphql-codegen. I really recommend using this approach, since backend schema updates and additions directly can be directly reflected in your frontend code revealing bugs and helping you code faster and more reliable.

Cupo answered 1/10, 2020 at 13:43 Comment(0)
A
3

As the error message is suggesting, Schema type definitions not allowed in queries., you can't add an enum definition in an operation document (ExecutableDefinition). You can only have operations (query, mutation, or subscription), or fragments definitions. That is, this is invalid:

enum OrderTypes {
  FULL_BUY
  PINK_BUY
}

mutation createOrderMutation {
  ...
}

If you want to define a local enum on your client, you can use the typeDefs property during ApolloClient initialization:

const client = new ApolloClient({
  cache,
  typeDefs: gql`
    enum OrderTypes {
      FULL_BUY,
      PINK_BUY
    }
  `,
});

And then you'll be able to see the OrderTypes enum on client-side introspection (i.e Apollo extension).

Pay attention to the client-side highlight: if you try to send a request with this enum for a non-client field (i.e without the @client directive) and it makes through your server, you'll get a schema error saying that the enum type does not exist, unless you define it on your backend.

Aer answered 18/9, 2019 at 17:51 Comment(5)
It's worth noting that client-side typeDefs are only used for introspection, not validation. It's not necessary to add any typeDefs to make use of local state.Shagreen
how set FULL_BUY enum in args? how access OrderTypes => FULL_BUY ?Uta
Good call, Daniel. OP question: if the mutation you're calling has an argument of type OrderTypes properly defined in the server, you can just use the enum values directly and it will work. e.g createOrderMutation(arg: FULL_BUY).Aer
But some time need through to variables and not directly.Alamein
This doesn't work for me. As Daniel said, the typeDefs don't add any value for validation. Even if I set these values, is there a way to use them in the gql query itself?Preordain

© 2022 - 2024 — McMap. All rights reserved.