【问题标题】:Pass Int Values to GraphQL将 Int 值传递给 GraphQL
【发布时间】:2020-07-24 05:23:44
【问题描述】:

我正在使用以下数据类型运行 graphql 查询:

mutation AddVehicle(
    $freeSeats: Number!
    $numberPlate: String!
    $userId: Number!
  )

在我的前端,我使用材料 ui 文本字段,默认情况下将输入作为字符串。要将其更改为整数,我在将参数传递给submitForm函数时使用了Number(freeSeats)etc。

但是,当我提交表单时,我仍然收到这些错误,这意味着这些值仍然作为字符串传递。我该如何解决这个问题?

 The specified value type of field `freeSeats` does not match the field type.
GraphQL error: The specified value type of field `userId` does not match the field type.

我也在submitForm函数的开头尝试了console.log(isNumber(freeSeats)。它打印真实。所以我知道字符串被转换为整数,但没有在突变中正确传递。

export default function AddVehiclePage() {
    const [isSubmitted, setIsSubmitted] = useState(false);
    const [isAdded, setIsAdded] = useState(false);
    const [errorMessage, setErrorMessage] = useState('');

    const [addVehicle] = useMutation(ADD_VEHICLE);

    const formik = useFormik({
        initialValues:{
            freeSeats: '',
            numberPlate: '',
            userId: '',
        },
        onSubmit:(values, actions) => {
          submitForm(Number(formik.values.freeSeats),formik.values.numberPlate,Number(formik.values.userId));           
           validationSchema:schema
        })

    let submitForm = (
        freeSeats: Number,
        numberPlate: string,
        userId: Number,
    ) => {
      setIsSubmitted(true);
      addVehicle({
        variables: {
          freeSeats: freeSeats,
          numberPlate: numberPlate,
          userId: userId,
        },
      })
        .then(({ data }: ExecutionResult<CreateVehicleResponse>) => {
          if (data !== null && data !== undefined) {
            setIsAdded(true);
          }
        })
        .catch((error: { message: string }) => {
          console.log('Error msg:' + error.message);
        });
    };

    return (
      <div>
                <Form
                  onSubmit={e => {
                    e.preventDefault();
                    formik.handleSubmit();
                  }}>
                  <div>
                    <TextField
                      variant="outlined"
                      margin="normal"
                      id="freeSeats"
                      name="freeSeats"
                      helperText={formik.touched.freeSeats ? formik.errors.freeSeats : ''}
                      error={formik.touched.freeSeats && Boolean(formik.errors.freeSeats)}
                      label="Free Seats"
                      value={formik.values.freeSeats}
                      onChange={props => {
                        formik.handleChange(props);
                        formik.handleBlur(props);
                      }}
                      onBlur={formik.handleBlur}
                    />
                    <br></br>
                    <TextField
                      variant="outlined"
                      margin="normal"
                      id="numberPlate"
                      name="numberPlate"
                      helperText={formik.touched.numberPlate ? formik.errors.numberPlate : ''}
                      error={formik.touched.numberPlate && Boolean(formik.errors.numberPlate)}
                      label="Number Plate"
                      value={formik.values.numberPlate}
                      onChange={props => {
                        formik.handleChange(props);
                        formik.handleBlur(props);
                      }}
                      onBlur={formik.handleBlur}
                    />
                    <br></br>
                    <TextField
                      variant="outlined"
                      margin="normal"
                      id="userId"
                      name="userId"
                      helperText={formik.touched.userId ? formik.errors.userId: ''}
                      error={formik.touched.userId && Boolean(formik.errors.userId)}
                      label="User Id"
                      value={formik.values.userId}
                      onChange={props => {
                        formik.handleChange(props);
                        formik.handleBlur(props);
                      }}
                      onBlur={formik.handleBlur}
                    />
                    <br></br>
                    <CustomButton                    
                      text={'Add'}
                    />
                  </div>
                </Form>
      </div>
    );
  }

【问题讨论】:

标签: javascript reactjs typescript graphql formik


【解决方案1】:

import { Int } from "type-graphql";

在突变中将类型从 Number 更改为 Int 有效。

【讨论】:

    【解决方案2】:

    graphql 中没有 Number 类型(检查文档)...可能应该是 Int 甚至 ID!

    在 typescript 中定义类型 Number 可能是不够的...https://spin.atomicobject.com/2018/11/05/using-an-int-type-in-typescript/

    如果 Int 足够(对于 graphQL)那么至少在这里做转换:

    addVehicle({
        variables: {
          freeSeats: parseInt(freeSeats),
    

    【讨论】:

    • 这样做会给我Argument of type 'Number' is not assignable to parameter of type 'string'.ts(2345)Probabaly,因为我首先将它们初始化为空字符串。 Null 不起作用,我该如何更改呢?
    • 如果我将freeSeats: Number更改为Id或int,则没有这种类型Cannot find name 'Int'.ts(2304)
    • 显示 graphql 类型,尝试 simpe parseInt(),在 Playground 中测试 api/mutation,比较浏览器开发工具/网络中的原始请求
    【解决方案3】:

    您可以使用parseInt(freeSeats) 将字符串转换为数字。

    请记住:

    • 在某些情况下,例如,如果字符串中的数字以 0 开头,这可能会给您一个不正确的值,因为有多种规则可以确定字符串中的数字是二进制、十六进制(以 6 为基数)还是八进制(以 8 为基数)而不是我们的标准以 10 为基数的计数系统。如果发生这种情况,您需要在方法中添加第二个参数,告诉它该数字以 10 为底:parseInt(freeSeats, 10)
    • 如果字符串格式不正确或为空,您仍然可能会得到 NaN 或 undefined 值。在尝试使用这些值之前,您可能需要检查它们。

    【讨论】:

    • parseInt() 在这种情况下也不起作用。我尝试在调用 submitForm 函数的地方使用它。
    • @Jnl 我对 Formik 不熟悉,但如果 parseInt 不起作用,那么我怀疑你正在处理不是数字的值(导致 NaN 或未定义),那就是导致它失败。查看代码,您可能会在这里获得一个数组而不是单个值。尝试在函数中添加控制台日志以在调用 submitForm 之前找出值是什么。这应该有助于弄清楚!
    • 我已经试过了。也许你可以看看这里:codesandbox.io/s/unruffled-browser-qjof4?file=/src/App.tsx
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    • 1970-01-01
    • 2015-11-18
    • 2020-09-16
    • 2020-11-19
    • 2021-06-01
    • 2013-07-13
    相关资源
    最近更新 更多