【问题标题】:Variables of required type not provided despited their validity尽管有效,但未提供所需类型的变量
【发布时间】:2020-04-06 06:40:41
【问题描述】:

我遇到了一个 GraphQL 错误,我似乎无法确定其来源。

所需类型“String!”的变量“$title”没有提供。
所需类型“String!”的变量“$body”没有提供。
所需类型“Int!”的变量“$price”没有提供。

错误信息很简单。此突变需要三个必需的变量,并且错误表明未提供任何类型,即使它们已明确提供。令人困惑的部分是使用 GraphQL Playground 的相同突变工作得非常好。在前端使用其他突变也可以正常工作。这告诉我这不是解析器的问题,也不是一般的服务器问题。

我用于突变的 GraphQL 如下所示:

export const CREATE_POST_MUTATION = gql`
    mutation CreatePost($title: String!, $body: String!, $price: Int!) {
        createPost(data: {
            title: $title, body: $body, price: $price
            }
        ){
            id
            title
        }
    }
`

我正在使用 Apollo 的 React Hook:

    const [createPost, { data, loading }] = useMutation(CREATE_POST_MUTATION, {
        onCompleted: data => {
            setCompleted({
                data,
            })
            setModal(true)
        },
        onError: data => {
            setCompleted({
                isOpen: true,
                error: true,
            })
        },
    }) 

表单的提交处理程序:

   const submitHandler = async (value) => {
        const { title, price, description } = value
        try {
            await createPost({
                variables: {
                    data: {
                        title,
                        body: description,
                        price: Number(price),
                    }
                }
            })
        } catch(err) {
            throw new Error(err)
        }
    }

控制台日志记录titlepricedescription 显示状态,以便它们正确传递给createPost。即使我直接将值分配给createPost 的变量而不传递状态,也会显示相同的错误。这告诉我这些错误与表单无关。

我将 Formik 和 Yup 用于子组件中的表单,但即使我将所有内容都剥离到只剩下 TextInput 的所有内容,也会显示相同的错误消息:

服务器端的 GraphQL 架构:

type Mutation {
    createPost(data: CreatePostInput!): Post!
}

input CreateUserInput {
    title: String!
    body: String!
    price: Int!
}

当我在服务器端控制台记录相应的变异解析器时,请求和参数甚至都没有到达那里。

【问题讨论】:

    标签: javascript reactjs react-native graphql react-apollo


    【解决方案1】:

    尽管您在data 中传递变量,但您的graphql 并不期望它们在data 中。所以改变

    await createPost({
      variables: {
        data: {
          title,
          body: description,
          price: Number(price),
        }
      }
    })
    

    await createPost({
      variables: {
        title,
        body: description,
        price: Number(price),
      }
    })
    

    【讨论】:

    • 或者,您也可以保持 createPost 调用不变并更改您的查询,使其只有一个具有适当类型的变量 ($data)。
    • 谢谢您,这非常有效。但是,我很困惑,因为我的 GraphQL 和 Schema 都有 data
    • 你的突变用mutation CreatePost($title: String!, $body: String!, $price: Int!)定义了变量,然后在突变内部,用data将它们传递到一个对象中。但是您必须以与定义变量完全相同的方式传递变量。
    【解决方案2】:

    我面临同样的挑战,我很沮丧,只是不知道我做错了什么。但最后我能够修复它。从您的代码中,我发现您做错的事情是(i)类型应该是 CreateUserInput! (ii) 变异后的 createPost 应该完全匹配,不考虑字母大小写。这应该可以解决您的错误。

         export const CREATE_POST_MUTATION = gql`
            mutation createPost(data: CreateUserInput!) {
                createPost(data: $data){
                    id
                    title
                }
            }
    

    【讨论】:

      【解决方案3】:

      我花了 8 个小时来解决这个问题。

      我的回答是基于来自@apollo/react-hooks 模块的useMutation

      1. 让用户拥有相同的(createPost or CreatePost)。别忘了在数据前面加上$ 符号。
      export const CREATE_POST_MUTATION = gql`
          mutation createPost($data: CreateUserInput!) {
              createPost(data: $data){
                  id
                  title
              }
          }
      
      1. 确保在 data 对象中传递所有突变数据。
      await createPost({   variables: {
         data: {
         title,
         body: description,
         price: Number(price),
            }}})
      
      1. 确保您具有当前输入类型和在服务器端代码中定义的相同createPost 函数。

      如需了解详情,请关注official docs

      【讨论】:

        猜你喜欢
        • 2019-03-22
        • 1970-01-01
        • 2019-05-01
        • 2020-10-18
        • 2021-07-18
        • 2021-03-13
        • 2022-01-03
        • 2019-11-13
        • 2020-08-23
        相关资源
        最近更新 更多