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) returnerror.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 错误数组未传递到组件中