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

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

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

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

  1. POST http://localhost:3000/graphql 400(错误请求) [GraphQL 错误]:消息:变量“$email”未定义。,位置:[object Object],[object Object],路径:未定义
  2. [GraphQL 错误]:消息:变量“$locationCity”未定义。位置:[object Object],[object Object],路径:未定义
  3. [GraphQL 错误]:消息:变量“$locationState”未定义。位置:[object Object],[object Object],路径:未定义
  4. [GraphQL 错误]:消息:变量“$locationCountry”未定义。位置:[object Object],[object Object],路径:未定义
  5. [GraphQL 错误]:消息:变量“$interests”未定义。位置:[object Object],[object Object],路径:未定义
  6. [网络错误]: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);

【问题讨论】:

    标签: graphql react-apollo


    【解决方案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 }
        );
      

      【讨论】:

        猜你喜欢
        • 2018-08-26
        • 2019-06-12
        • 2019-01-26
        • 2020-03-30
        • 2021-11-20
        • 2019-07-28
        • 2019-07-11
        • 2015-04-06
        • 1970-01-01
        相关资源
        最近更新 更多