React Apollo GraphQL Mutation returns 400(错误请求)

React Apollo GraphQL Mutation returns 400 (bad request)

我对 React Apollo 和 graphQL 还很陌生。我正在尝试创建一个编辑个人资料表单,将数据添加到用户个人资料中。当我点击提交时没有任何反应并在控制台日志中得到错误:

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

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

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

我认为问题在于您的 突变输入字段 架构中定义的字段 不同 .

您的架构有:

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.

看 您正在声明采用一个参数的突变,并且在解析器中,它使用电子邮件、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

}

提交时告诉我它是否有效

我发现我弄错了。而不是:

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 }
  );