React Apollo GraphQL Mutation 返回 400(错误请求)

Posted

技术标签:

【中文标题】React Apollo GraphQL Mutation 返回 400(错误请求)【英文标题】:React Apollo GraphQL Mutation returns 400 (bad request) 【发布时间】:2020-01-15 17:50:51 【问题描述】:

我对 React Apollo 和 graphQL 非常陌生。我正在尝试创建一个编辑配置文件表单,将数据添加到用户配置文件。当我单击提交时,没有任何反应并在控制台日志中出现错误:

理想情况下,我希望表单最初呈现用户之前输入的任何数据,以便在提交表单并且他们没有更改所有输入时,他们没有更改的输入不会被覆盖MongoDB数据库。

所有和任何建议将不胜感激!谢谢!

    POST http://localhost:3000/graphql 400(错误请求) [GraphQL 错误]:消息:变量“$email”未定义。,位置:[object Object],[object Object],路径:未定义 [GraphQL 错误]:消息:变量“$locationCity”未定义。位置:[object Object],[object Object],路径:未定义 [GraphQL 错误]:消息:变量“$locationState”未定义。位置:[object Object],[object Object],路径:未定义 [GraphQL 错误]:消息:变量“$locationCountry”未定义。位置:[object Object],[object Object],路径:未定义 [GraphQL 错误]:消息:变量“$interests”未定义。位置:[object Object],[object Object],路径:未定义 [网络错误]:ServerError:响应不成功:收到状态码400

在我的 schema.js 中,我有以下内容:

editOtherProfileDetails(email: String!, locationCity: String!, locationState: String!, locationCountry: String!, interests: String!): User

在我的 resolvers.js 中,我有以下内容:

editOtherProfileDetails: async (root,  email, locationCity, locationState, locationCountry, interests ,  User ) => 

      const user = await User.findOneAndUpdate( email , 
         $set:  locationCity: locationCity  , 
         $set:  locationState: locationState  , 
         $set:  locationCountry: locationCountry  , 
         $set:  interests: interests  , 
         new: true 
      );

      if (!user) 
        throw new Error('User Not Found');
      

      return user;
    ,

在我的 index.js 中,我有:

export const EDIT_OTHER_PROFILE_DETAILS = gql`
    mutation($locationCountry: String!)
        editOtherProfileDetails(email: $email, locationCity: $locationCity, locationState: $locationState, locationCountry: $locationCountry, interests: $interests)
            email
            locationCity
            locationState
            locationCountry
            interests
        
    
`;

在我的 editProfile.js 中,我有以下内容:


    import React,  Fragment  from 'react';
    import  Mutation  from 'react-apollo';
    import GET_USER_PROFILE, EDIT_OTHER_PROFILE_DETAILS, PROFILE_PAGE  from './../../queries';
    import  withRouter  from 'react-router-dom';
    import toastr from 'toastr';

    const initialState = 
      locationCity: '',
      locationState: '',
      locationCountry: '',
      interests: '',
      error: ''
    

    class EditOtherProfileMutations extends React.Component 

      constructor(props) 
        super(props);
        this.state = 
          locationCity: '',
          locationState: '',
          locationCountry: '',
          interests: '',
          error: ''
        
      

      componentDidMount() 
        if (this.props.profile) 
          this.setState(
            locationCity: this.props.profile.locationCity,
            locationState: this.props.profile.locationState,
            locationCountry: this.props.profile.locationCountry,
            interests: this.props.profile.interests
          );
        
        toastr.options = 
          "closeButton": false,
          "debug": false,
          "newestOnTop": true,
          "progressBar": true,
          "positionClass": "toast-bottom-right",
          "preventDuplicates": false,
          "onclick": null,
          "showDuration": "300",
          "hideDuration": "1000",
          "timeOut": "5000",
          "extendedTimeOut": "1000",
          "showEasing": "swing",
          "hideEasing": "linear",
          "showMethod": "fadeIn",
          "hideMethod": "fadeOut"
        
      

      handleChange(event) 
        const name = event.target.name;
        const value = event.target.value;
        this.setState(
          [name]: value.charAt(0).toUpperCase() + value.substr(1).toLowerCase()
        );
      

      handleSubmit(event, editOtherProfileDetails) 
        event.preventDefault();
        editOtherProfileDetails().then(async () => 
          toastr.success('We have updated your details!', 'Saved!');
        ).catch(error => 
          this.setState(
            error: error.graphQLErrors.map(x => x.message)
          )
          // console.error("ERR =>", error.graphQLErrors.map(x => x.message));
        );
      

      render() 

        const   locationCity, locationState, locationCountry, interests  = this.state
        const userName = this.props.session.getCurrentUser.userName;
        this.state;

        return (
          <Fragment>

            <Mutation
              mutation=EDIT_OTHER_PROFILE_DETAILS
              variables= email: this.props.session.getCurrentUser.email, locationCity, locationState, locationCountry, interests 
              refetchQueries=() => [
                 query: GET_USER_PROFILE ,
                 query: PROFILE_PAGE, variables:  userName  
              ]>

              /* eslint-disable */
              (editOtherProfileDetails,  data, loading, error ) => 
              /* eslint-enable */

                return (

                  <form className="form" onSubmit=event => this.handleSubmit(event, editOtherProfileDetails)>

                    <div className="form_wrap">



                      <div className="form_row">

                        <div className="form_item">
                          <div className="form_input">
                            <span className="edit_profile_span">City</span>
                            <input type="text" name="locationCity" placeholder="City" value=locationCity style= textTransform: "capitalize" onChange=this.handleChange.bind(this)/>
                            <span className="bottom_border"></span>
                          </div>
                        </div>

                      </div>

                      <div className="form_row">

                        <div className="form_item">
                          <div className="form_input">
                            <span className="edit_profile_span">State</span>
                            <input type="text" name="locationState" placeholder="State" value=locationState style= textTransform: "capitalize" onChange=this.handleChange.bind(this)/>
                            <span className="bottom_border"></span>
                          </div>
                        </div>

                      </div>

                      <div className="form_row">

                        <div className="form_item">
                          <div className="form_input">
                            <span className="edit_profile_span">Country</span>
                            <input type="text" name="locationCountry" placeholder="Country" value=locationCountry style= textTransform: "capitalize" onChange=this.handleChange.bind(this)/>
                            <span className="bottom_border"></span>
                          </div>
                        </div>

                      </div>

                      <div className="form_row">

                        <div className="form_item">
                          <div className="form_input">
                            <span className="edit_profile_span">Interests</span>
                            <input type="text" name="interests" placeholder="Interests (e.g Sports, Wine, Outdoors ect.)" value=interests style= textTransform: "capitalize" onChange=this.handleChange.bind(this)/>
                            <span className="bottom_border"></span>
                          </div>
                        </div>

                      </div>

                      <div className="form_buttons">
                        <button type="submit" className="btn">
                        Save changes</button>
                      </div>

                    </div>

                  </form>

                );
              

            </Mutation>

          </Fragment>
        )
      
    

    export default withRouter(EditOtherProfileMutations);

【问题讨论】:

【参考方案1】:

我认为问题在于您的 mutation 输入字段 与您的 schema 中定义的那些相同。

您的架构具有:

editOtherProfileDetails(
 email: String!, 
 locationCity: String!, 
 locationState: String!, 
 locationCountry: String!, 
 interests: String!
): User

你定义你的突变如下:

mutation($locationCountry: String!) ... 

输入参数必须匹配,所以我认为如果你这样定义你的突变,它会起作用:

mutation NameOfYourMutation(
 $email: String!, 
 $locationCity: String!, 
 $locationState: String!, 
 $locationCountry: String!, 
 $interests: String!
)  ... 

此外,正如您所料,这将慢慢变得难以维护。 我建议看看input objects。

【讨论】:

【参考方案2】:

看 您正在声明带有一个参数的突变,并且在解析器中,它使用电子邮件、locationCity、locationState、locationCountry,对此参数感兴趣但未声明它会导致问题您应该使用 $locationCity 和其他但它没有数据文件应该作为论据 像这个形状

      mutation($locationCountry: String!
    ,$locationCity: String!, 
     $locationState: String!, 
     $locationCountry: String!, 
     $interests: String!)
editOtherProfileDetails(email: $email, locationCity: $locationCity, locationState: $locationState, locationCountry: $locationCountry, interests: $interests)

 email
            locationCity
            locationState
            locationCountry
            interests


在提交时告诉我它是否有效

【讨论】:

感谢您的解决方案,它消除了所有错误,但现在我收到一个新错误:GraphQL 错误]:消息:回调必须是一个函数,得到 [object Object],位置: [object Object],路径:editOtherProfileDetails 查看这段代码之后 (editOtherProfileDetails, data, loading, error ) => add if(error) return

error.message

if(loading ) 返回

loading

以尝试删除箭头函数并告诉我从 editOtherProfileDetails 中的解析器中删除 => 告诉我是否有任何进展
对不起,我不确定你的意思!【参考方案3】:

我发现我犯了一个错误。而不是:

const user = await User.findOneAndUpdate( email , 
     $set:  locationCity: locationCity  , 
     $set:  locationState: locationState  , 
     $set:  locationCountry: locationCountry  , 
     $set:  interests: interests  , 
     new: true 
  );

我需要说:

const user = await User.findOneAndUpdate( email , 
     $set:  locationCity: locationCity, locationState: locationState, locationCountry: locationCountry, interests: interests  , 
     new: true 
  );

【讨论】:

以上是关于React Apollo GraphQL Mutation 返回 400(错误请求)的主要内容,如果未能解决你的问题,请参考以下文章

GraphQL“必须提供查询字符串” graphql-tag react-apollo

React + Apollo:GraphQL 错误数组未传递到组件中

使用 Express-GraphQL 和 React-Apollo 订阅 GraphQL

React、Apollo 2、GraphQL、身份验证系统

React-Apollo-Prisma-Graphql

react-apollo 没有连接到我的 graphql 本地服务器