如何在阿波罗客户端中使用枚举?

时间:2019-09-18 17:42:05

标签: graphql apollo apollo-client vue-apollo

OrderTypesEnum.gql

中的枚举定义
enum OrderTypes {
  full_buy
  pink_buy
}

导入OrderTypesEnum.gql文件

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

但是,如何获取代码中的枚举?

我使用OrderTypes.full_buy时遇到了一些错误:

   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"

OrderTypes类型枚举的检查

enter image description here

3 个答案:

答案 0 :(得分:2)

由于错误消息提示Schema type definitions not allowed in queries.,因此您不能在操作文档(ExecutableDefinition)中添加枚举定义。您只能具有操作(查询,变异或预订)或片段定义。也就是说,这是无效的:

enum OrderTypes {
  FULL_BUY
  PINK_BUY
}

mutation createOrderMutation {
  ...
}

如果要在客户端上定义本地枚举,则可以在ApolloClient初始化期间使用typeDefs属性:

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

然后您将能够在客户端自省(即Apollo扩展名)上看到OrderTypes枚举。

请注意客户端突出显示:如果您尝试使用此枚举发送非客户端字段的请求(即没有@client指令),并且该请求通过您的服务器,则会出现架构错误说枚举类型不存在,除非您在后端定义它。

答案 1 :(得分:2)

先决条件:

我们必须在GraphQL模式中定义(服务器端,不需要客户端配置)

假设我们已定义:

enum SomeEnumType {
    OPTION1,
    OPTION2,
    OPTION3
}

我们还必须以适当的方式配置Apollo客户端并将其与GraphQL API相连。

然后在客户端:

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

只有这样做,您才能在查询或变异中将枚举作为变量传递。例如,使用useMutation钩子,我们现在可以进行如下更改:

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

由于我们在gql标记中的类型定义与在Schema中的定义相等,所以GraphQL会将变量视为字符串,尽管我们将其指定为字符串。

如果我们想使用typescript枚举将枚举传递给我们的变量,我们可以这样做:

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

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

答案 2 :(得分:0)

现在,我遇到了同样的问题。我找到了这样的解决方案。也许它可以解决您的问题。

import { Component, OnInit } from '@angular/core';
import { MatSnackBar } from '@angular/material';
import { Router } from '@angular/router';
import { slugify } from '../../helpers/slugify';
import { SEOService } from '../../services/seo.service';

import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MustMatch } from '../../helpers/must-match-validator';

import { MAT_MOMENT_DATE_FORMATS, MomentDateAdapter } from '@angular/material-moment-adapter';
import { DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE } from '@angular/material/core';

import { CreateUserInput, RegisterPageRegisterGQL, Roles } from '@generated-types';

@Component({
  selector: 'app-register',
  templateUrl: './register.component.html',
  styleUrls: [
    './register.component.scss'
  ],
  providers: [
    // The locale would typically be provided on the root module of your application. We do it at
    // the component level here, due to limitations of our example generation script.
    { provide: MAT_DATE_LOCALE, useValue: 'tr-TR' },

    // `MomentDateAdapter` and `MAT_MOMENT_DATE_FORMATS` can be automatically provided by importing
    // `MatMomentDateModule` in your applications root module. We provide it at the component level
    // here, due to limitations of our example generation script.
    { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] },
    { provide: MAT_DATE_FORMATS, useValue: MAT_MOMENT_DATE_FORMATS },
  ],
})

export class RegisterComponent implements OnInit {
  registerForm: FormGroup;
  submitted = false;
  error: any;
  genders: any = ['Kadın', 'Erkek', 'Belirtmek İstemiyorum'];

  user: CreateUserInput;

  constructor(
    public snackBar: MatSnackBar,
    private router: Router,
    private seoService: SEOService,
    private formBuilder: FormBuilder,
    private _adapter: DateAdapter<any>,
    private registerPageRegisterGQL: RegisterPageRegisterGQL,
  ) { }

  // convenience getter for easy access to form fields
  get f() { return this.registerForm.controls; }

  ngOnInit() {
    // datepicker locale
    this._adapter.setLocale('tr');
    // seo service
    this.seoService.addDefaultMetaTags();
    this.seoService.meta.updateTag({ name: 'robots', content: 'noindex' });
    this.seoService.addTitle('Kayıt Ol | kitaphub');
    // form validator
    this.registerForm = this.formBuilder.group({
      userName: ['', Validators.required],
      email: ['', [Validators.required, Validators.email]],
      firstName: ['', Validators.required],
      lastName: ['', Validators.required],
      password: ['', [Validators.required, Validators.minLength(6)]],
      confirmPassword: ['', Validators.required],
      gender: ['', Validators.required],
      dateOfBirth: ['', Validators.required],
      acceptTerms: [false, Validators.requiredTrue]
    }, {
      validator: MustMatch('password', 'confirmPassword')
    });
  }

  async onSubmit() {
    console.log('onSubmit');
    this.submitted = true;

    // stop here if form is invalid
    if (this.registerForm.invalid) {
      return;
    }

    // display form values on success
    alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.registerForm.value, null, 4));

    this.registerPageRegisterGQL.mutate({
      user: {
        userName: this.registerForm.value.userName,
        email: this.registerForm.value.email,
        slug: slugify(this.registerForm.value.userName),
        firstName: this.registerForm.value.firstName,
        lastName: this.registerForm.value.lastName,
        password: this.registerForm.value.password,
        gender: this.registerForm.value.gender,
        role: Roles.MEMBER
      }
    }).subscribe(({ data }) => {
      console.log('got data:', data);
      this.openSnackBar('KAYIT İŞLEMİ TAMAMLANDI');
    }, (error: any) => {
      this.handleError(error);
      console.log('there was an error sending', error);
    });
  }

  onReset() {
    this.submitted = false;
    this.registerForm.reset();
  }

  handleError(error: any) {
    this.error = error.message;
  }

  openSnackBar(text: string) {
    return this.snackBar.open(text, 'X', { horizontalPosition: 'right', verticalPosition: 'top', duration: 3000 });
  }

}